I am trying to write these parameters in a file .txt, but when I open the file (even before that it shows me a warining about the encoding) it appers like a bug, full of ????, like this:
$�U�z�G��?xpto%�U\���(\�?xpto&�Uףp=
��?xpto'�UR���Q�?xpto(�U�������?xpto)�UH�z�G�?xpto*�U��(\���?xpto+�U>
ףp=�?xpto,�U���Q��?xpto-�U433333�?xpto
I've searched a lot about but as it is a specifically error, i cannot find nothing about it.
What is happening?
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
typedef struct
{
int age;
double height;
char name[64];
} Person;
void printPersonInfo(Person *p)
{
printf("Person: %s, %d, %f\n", p->name, p->age, p->height);
}
int main (int argc, char *argv[])
{
FILE *fp = NULL;
int i;
Person p = {35, 1.65, "xpto"};
/* Validate number of arguments */
if(argc != 2)
{
printf("USAGE: %s fileName\n", argv[0]);
return EXIT_FAILURE;
}
/* Open the file provided as argument */
errno = 0;
fp = fopen(argv[1], "w");
if(fp == NULL)
{
perror ("Error opening file!");
return EXIT_FAILURE;
}
/* Write 10 itens on a file */
for(i = 0 ; i < 10 ; i++)
{
p.age = p.age+1;
p.height = p.height+0.03;
fwrite(&p, sizeof(Person), 1, fp);
}
fclose(fp);
return EXIT_SUCCESS;
}
The fwrite function is writing the binary representation of the struct p to the file. If you want to write text, use fprintf:
fprintf(fp, "%d %f %s\n", p.age, p.height, p.name);
Related
I am using C in Visual Studio via a remote Linux server. I want to read a file and store the contents in a array of structs. Every time I try to read a line using fscanf() it seg faults. Thanks in advance.
Format of the file I'm trying to read:
F150 5.4 28000 white
RAM1500 5.7 32000 orange
car 4.5 12000 green
truck 6.1 55000 black
Here's a simplified version my program as the other parts function fine:
#include <stdlib.h>
#include <stdio.h>
struct data {
char name[20];
float floatNum;
int intNum;
char color[20];
} temp;
int scan(void) {
int size = 0;
FILE *data;
data = fopen("./hw3.data", "r");
while (1) {
fscanf(data, "%s %f %d %s", temp.name, &temp.floatNum,
&temp.intNum, temp.color);
if (feof(data))
break;
size++;
}
return size;
}
void load(int size, struct data autos[]) {
int i;
FILE *data;
data = fopen("./hw3.data", "r");
for (i = 0; i < size; i++) {
fscanf(data, "%s %f %d %s", autos[i].name, &autos[i].floatNum,
&autos[i].intNum, autos[i].color);
}
}
int main() {
int size;
struct data *autos;
size = scan();
autos = malloc(size * sizeof(struct data));
load(size, autos);
return 0;
}
There are multiple possible causes for problems:
you do not test if fopen() succeeds: if the file cannot be opened, the FILE pointer data will be null, causing undefined behavior in fscanf(), possibly a seg fault.
you do not test if malloc succeeds... again causing a seg fault if memory cannot be allocated.
you should close the FILE after reading
your test for feof() is incorrect: it might be true after successfully reading the last item, causing it to be ignored and you might never reach the end of file if one of the items cannot be read. You should just test the return value of fscanf(): it returns the number of successful conversions, so 4 in your case.
you should use %19s to avoid writing beyond the end of the targets arrays, another potential source of undefined behavior.
Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct data {
char name[20];
float floatNum;
int intNum;
char color[20];
};
int scan(const char *filename) {
struct data temp;
int size = 0;
FILE *data = fopen(filename, "r");
if (data == NULL) {
fprintf(stderr, "cannot open %s: %s\n", filename, strerror(errno));
return -1;
}
while (fscanf(data, "%19s %f %d %19s",
temp.name, &temp.floatNum,
&temp.intNum, temp.color) == 4) {
size++;
}
fclose(data);
return size;
}
int load(const char *filename, int size, struct data autos[]) {
int i;
FILE *data = fopen(filename, "r");
if (data == NULL) {
fprintf(stderr, "cannot open %s: %s\n", filename, strerror(errno));
return -1;
}
for (i = 0; i < size; i++) {
if (fscanf(data, "%19s %f %d %19s",
autos[i].name, &autos[i].floatNum,
&autos[i].intNum, autos[i].color) != 4)
break;
}
fclose(data);
return i;
}
int main() {
char filename[] = "./hw3.data";
int size = scan(filename);
if (size < 0)
return 1;
if (size > 0) {
struct data *autos = malloc(size * sizeof(struct data));
if (autos == NULL) {
fprintf(stderr, "cannot allocate %zu bytes\n", size * sizeof(struct data));
return 1;
}
int n = load(filename, size, autos);
for (int i = 0; i < n; i++) {
printf("%s %g %d %s\n", autos[i].name, autos[i].floatNum,
autos[i].intNum, autos[i].color);
}
free(autos);
}
return 0;
}
I'm trying to read a file and put the values in a Struct to sort then, but my code isn't working.
#include <stdio.h>
#include <stdlib.h>
struct person
{
char Nome[50];
int Idade;
double Altura;
};
int main ()
{
FILE *infile;
struct person input;
infile = fopen ("pessoas.txt", "r");
if (infile == NULL)
{
fprintf(stderr, "\nError opening file\n");
exit (1);
}
while(fread(&input, sizeof(struct person), 1, infile))
printf ("Nome = %s Idade = %d Altura = %f\n", input.Nome,
input.Idade, input.Altura);
// close file
fclose (infile);
return 0;
}
My file is:
Maria
15
1.6
Joao
21
1.8
Abel
23
1.7
Joana
40
1.6
You can use fscanf() to read file & populate the structure.
#include <stdio.h>
#include <stdlib.h>
struct person
{
char Nome[50];
int Idade;
double Altura;
};
int main ()
{
FILE *infile;
struct person input;
infile = fopen ("pessoas.txt", "r");
if (infile == NULL)
{
fprintf(stderr, "\nError opening file\n");
exit (1);
}
while(3 != fscanf(infile, "%49s %d %lf", input.Nome, &input.Idade, &input.Altura))
printf ("Nome = %s Idade = %d Altura = %lf\n", input.Nome, input.Idade, input.Altura);
// close file
fclose (infile);
return 0;
}
I am trying to load a binary file but I am getting:
realloc(): invalid next size
This is the struct im using in the following code:
typedef struct {
int from;
int to;
int cost;
} edge_t;
typedef struct {
int size;
int capacity;
edge_t *edges;
} graph_t;
Code:
#include <stdlib.h>
#include <stdio.h>
#include "graph.h" //this is the struct above
void load_bin(const char *fname, graph_t *graph) {
graph->capacity = 1;
graph->size = 0;
graph->edges = malloc(graph->capacity*sizeof(edge_t));
FILE *myFile;
myFile = fopen(fname, "r");
if (myFile == NULL) {
fprintf(stderr, "Error: file not found!\n");
exit(100);
}
while(fread(&(graph->edges[graph->size].from), sizeof(edge_t), 3, myFile) == 3){
graph->size++;
if(graph->capacity == graph->size){
graph->capacity *=2;
graph->edges=realloc(graph->edges, sizeof(edge_t)*graph->capacity);
}
}
}
EDIT: Tried to make a verifiable example, as requested.
int main(int argc, char *argv[])
{
int ret = 0;
if (argc > 2) {
graph_t *graph = allocate_graph();
fprintf(stderr, "Load bin file '%s'\n", argv[1]);
load_bin(argv[1], graph);
fprintf(stderr, "Save txt file '%s'\n", argv[2]);
save_txt(graph, argv[2]);
free_graph(&graph);
} else {
fprintf(stderr, "Usage %s input_bin_file output_txt_file\n", argv[0]);
ret = -1;
}
return ret;
}
This function and load are located in the same file and are called from main
graph_t *allocate_graph(){
return calloc(1, sizeof(graph_t));
}
From what I checked, it means I do not change the size properly on realloc, but I thought i was?
Thanks.
the while is invalid, must be
while(fread(&(graph->edges[graph->size].from), sizeof(edge_t), 1, myFile) == 1)
because currently you read 3 elements and go out of the allocated memory
P.S. out of that, are you sure you read correctly the file ? you suppose the content is consecutive 3 values on sizeof(int) bytes, without separator etc
I wrote this code to read a variable in a .txt file, ignore the first character and convert into a integer.It works but looks dumb, is there a better way to do this? I'm using just one string here but it's supposed to work with four.
void read(char a[])
{
int i;
char a1[3];
for (i = 0; i<3; ++i){
a1[i]= a[i+1];
}
int b1 = atoi(a1);
}
int main()
{
FILE *file;
file = fopen( "file.txt", "r");
if (file == NULL) {
printf( "Arquivo nao encontrado\n");
}
char a[4];
fscanf(file, "%s\n",&a);
read(a);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
const char filename[] = "file.txt";
FILE *fp = fopen(filename, "r");
if (fp == 0)
{
fprintf(stderr, "Failed to open file %s for reading\n", filename);
return(EXIT_FAILURE);
}
int value;
if (fscanf(fp, "%*c%d", &value) != 1)
{
fprintf(stderr, "Failed to read integer value from file %s\n", filename);
fclose(fp);
return EXIT_FAILURE;
}
printf("Read %d\n", value);
fclose(fp);
return 0;
}
The %*c reads a single character but does not assign it. The * to suppress an assignment is a general mechanism in the scanf()
family of functions.
Untested code.
I'm trying to make a program that reads a file with list of names. The number of those names can vary, as well as the names lengths. I want to store them in an array of arrays of char, and read each row as a string to later open the file that corresponds to the name in question. But when I try to open the first one, I have an error opening file.
I'm totally out of ideas.
Help, please?
Here is the code relevant to this action:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
int glimps(char *fname);
int write_av(char *fname, int NumbFiles);
int clr(char *fname);
int readFile(char *fname, int i);
double *dalpha, *alpha, *Ln_t, *LnLnA, Conc;
long *time, *weights, *Lmax, Nmax;
char *av_file, **in_files, *antetka;
/****************************************************************************/
int main(int argc, char *farg[])
{
int i, NumbFiles, flag;
long row;
char *a1;
FILE *fp;
av_file = farg[1];
printf("av_file = %s\n",av_file);
NumbFiles = glimps(av_file);
in_files = (char **) malloc (sizeof(char *) * NumbFiles);
for (i=0 ; i<NumbFiles ; i++)
in_files[i] = (char *) malloc (sizeof(char) * 200);
Lmax = (long *) calloc((size_t) NumbFiles, sizeof(long));
if((in_files == NULL)||(Lmax==NULL)) printf("Грешка при read алок.\n, "), exit(-1);
if (flag = readFile(av_file, -1))
printf("Error in read av_file %s\n", av_file), exit(-1);
weights = (long *) calloc((size_t) Nmax, sizeof(long));
for(i = 0; i<Nmax; i++) weights = 0;
for(i = 0; i<NumbFiles; i++)
{
//if (flag = readFile(&(*in_files[i]), i))
if (flag = readFile(in_files[i], i))
printf("Error in in_files[%d], %s\n",i, &(*in_files[i])), exit(-1);
}
if (flag = write_av(av_file, NumbFiles))
printf("Error in write_av(%s)\n,", av_file), exit(-1);
exit(0);
}
/****************************************************************************/
int glimps(char *fname)
{
FILE *fp;
char buf[140];
int cnt=0;
fp = fopen (fname, "r");
while (fgets(buf,140,fp) )
{
cnt++;
}
fclose(fp);
return (cnt);
}
/****************************************************************************/
int readFile(char *fname, int k)
{
int cnt=0;
FILE *fp;
char buf[200], dummy[13];
printf("fname is %s\n", fname); getchar();
fp = fopen (fname, "r");
if(fp==(NULL)) return(-1);
if(!strcmp(fname,av_file) )
{
while (fgets(in_files[cnt++],200,fp) );
}
else
{
printf("read TUK!\n"); getchar();
fgets(buf,200,fp);
sscanf(buf,"%s %s %s %s %s %s %s %ld %s %s %lf\n",
dummy, dummy,dummy,dummy,dummy,dummy,dummy, &Lmax[k],
dummy, dummy, &Conc);
fgets(buf,200,fp);
sscanf(buf,"%s\n", antetka);
printf("read TUK!\n"); getchar();
while (fgets(buf,200,fp))
{
sscanf(buf,"%ld %lf %lf %s %lf %lf\n",
&time[cnt], &dalpha[cnt], &alpha[cnt], dummy, &Ln_t[cnt],
&LnLnA[cnt]);
weights[cnt++]++;
}
}
fclose(fp);
return (0);
}
...
Console Output:
> ./avr alpha_cubeL.C0.010
av_file = alpha_cubeL.C0.010
fname is alpha_cubeL.C0.010
fname is alpha_cubeL100C0.010
Error in read in_files[0], alpha_cubeL100C0.010
> ls alpha_cubeL100C0.010
alpha_cubeL100C0.010
What happens is that in the readFile function, you read the main file given as argument to make (from the content) several file names in in_files[i], but fgets reads lines including the CR or CRLF (ie the end of line character(s)). Thus later in the program, readFile fails as it tries to open filename + CR [LF].
You may just add a trim function near the top of your program, like
void trim(char *s) {
int i,l = strlen(s);
for (i=l-1 ; i>=0 && (s[i]==10 || s[i]==13) ; i--) s[i] = 0;
}
that removes CR and/or LF that end a string s, and then change the readFile function to trim the file names read in each line, like
while (fgets(in_files[cnt++],200,fp) ) {
trim(in_files[cnt-1]); // cnt-1, or do the cnt++ here (and not above...)
}
Then the files can be opened...
(this is probably not the only problem in this program, but this is a good start)