-
File IO
I want to scan a text file:
Code:
jones,1,2,3,4
smith,2,3,4,5
john,57,65,4,2
catherine,25,64,78,65
I want ask a few questions:
(1) Can anybody give me any functions on how I can use to do this (or point me in the general direction).
I tried using fscanf, but it keeps on giving me the wrong answers.
Below is the code
Code:
#include <stdio.h>
#define MAXSTUDENT 40
#define MAXNAME 20
typedef struct student_t{
char name[(MAXNAME+1)];
int exam1,exam2, exam3, exam4;
float average;
};
int main(void)
{
FILE *readfile;
int num=4;
int check;
student_t student[MAXSTUDENT] = {0};
int i;
if((readfile=fopen("datafile.txt","rt"))==NULL)
{
printf("Error, unable to read file. Program exiting");
return (1);
}else
{
for(i=0,check=0;i<num;i++)
{
do
{
check=fscanf(readfile,"%s,%d,%d,%d,%d",&student[i].name,&student[i].exam1,&student[i].exam2,&student[i].exam3,&student[i].exam4);
printf(".");
}while(check==4);
printf("*");
}
printf("\n%d",student[0].exam1);
printf("\n%d",student[0].exam2);
printf("\n%d",student[0].exam3);
printf("\n%d",student[0].exam4);
}
return 0;
}
Thanks in advance.
-
>>while(check==4)
fscanf() returns the numbers of items extracted, which will be 5 if all goes well, not 4.
In the fscanf() call, this:
>>&student[i].name
should be
>>student[i].name
as name is a array, and therefore already a pointer.
Other ways would be to use fgets() and load a line at a time into memory, then do the parsing manually. This will give you greater control, but is more effort.
[edit]
And you keep overwriting the same array element as you never increment i in the do/while loop.
-
still stuck
I am still stuck. How would you tell fscanf to read a new line from the data and store it?
I can't give it a value like EOF, since this would mean the end of the file, not a new line.
Again, thanks in advance =).
-
Why do you want the newline?
Anyway, try a %c.
-
I've tried changing &student[i].name to student[i].name, but i still can't read the file. The compiler gives something like:
"Data if 'int' supplied where pointer is required"
Code:
#include <stdio.h>
#define MAXSTUDENT 40
#define MAXNAME 20
typedef struct student_t{
char name[(MAXNAME+1)];
int exam1,exam2, exam3, exam4;
float average;
};
int main(void)
{
FILE *readfile;
int num=4;
int check;
int i=0;
student_t student[MAXSTUDENT] = {0};
if((readfile=fopen("datafile.txt","rt"))==NULL)
{
printf("Error, unable to read file. Program exiting");
return (1);
}else
{
while((fscanf(readfile,"%s,%d,%d,%d,%d",student[i].name,student[i].exam1,student[i].exam2,student[i].exam3,student[i].exam4)!=EOF))
{
printf(".");
i++;
}
printf("\n%d",student[0].exam1);
printf("\n%d",student[0].exam2);
printf("\n%d",student[0].exam3);
printf("\n%d",student[0].exam4);
}
fclose(readfile);
return 0;
}
-
Code:
typedef struct {
char name[(MAXNAME+1)];
int exam1,exam2, exam3, exam4;
float average;
}student_t;
In the fscanf() line, all the ints need to have the & put back on them:
>>&student[i].exam1
only the name can go without.
To help solve your puzzle, print out the name as well as the numbers:
Code:
printf("\n%s",student[0].name);
printf("\n%d",student[0].exam1);
printf("\n%d",student[0].exam2);
printf("\n%d",student[0].exam3);
printf("\n%d",student[0].exam4);
-
For some reason, fscanf seams to be only taking a whole line from the text file and storing it in the string member of the structure. But I want the line to be stored in seperately into different members in the structure. Below is my code:
Code:
#include <stdio.h>
#define MAXSTUDENT 40
#define MAXNAME 20
typedef struct{
char name[(MAXNAME+1)];
int exam1,exam2, exam3, exam4;
float average;
}student_t;
int main(void)
{
FILE *readfile;
student_t student [MAXSTUDENT];
int i=0;
if((readfile=fopen("datafile.txt","rt"))==NULL)
{
printf("Error, unable to read file. Program exiting");
return (1);
}else
{
while((fscanf(readfile,"%s,%d,%d,%d,%d",student[i].name,&student[i].exam1,&student[i].exam2,&student[i].exam3,&student[i].exam4)!=EOF))
{
printf(".");
++i;
}
printf("\n%s",student[0].name);
printf("\n%d",student[0].exam1);
printf("\n%d",student[0].exam2);
printf("\n%d",student[0].exam3);
printf("\n%d",student[0].exam4);
}
fclose(readfile);
return 0;
}
However for the print out i seem be getting something like this:
Code:
jones,1,2,3,4 //for student[0].name
0 //for student[0].exam1
2011641991 //for student[0].exam2
2 //for student[0].exam3
66 //for student[0].exam4
But I want it to be something like this:
Code:
jones //for student[0].name
1 //for student[0].exam1
2 //for student[0].exam2
3 //for student[0].exam3
4 //for student[0].exam4
Would somebody please help? I've been stuck on this for hours. =(
Thanks.
-
Well, it's because he is getting everything as string, I suggest you in the file change it to something like this:
And not jones,1,2,3,4.
Also in fscanf you don't need those ',' just use it as:
Code:
fscanf(readfile,"%s%d%d%d%d",student[i].name,&student[i].exam1,&student[i].exam2,&student[i].exam3,&student[i].exam4)
-
yes
Yes, i know that placing spaces in between would make it easier. But i want to know why it doesn't work it I use the comma operator?
If it does, how can I make fscanf read the line of text?
-
>But i want to know why it doesn't work it I use the comma operator?
The %s specifier is whitespace-delimited. You could use the %[ specifier instead.
Code:
/* test.txt
jones,1,2,3,4
smith,2,3,4,5
john,57,65,4,2
catherine,25,64,78,65
*/
#include <stdlib.h>
#include <stdio.h>
#define MAXNAME 20
struct student
{
char name[(MAXNAME+1)];
int exam1,exam2, exam3, exam4;
float average;
};
int main(void)
{
const char filename[] = "test.txt";
FILE *file = fopen(filename, "r");
if ( file != NULL )
{
struct student s;
while ( fscanf(file, "%[^,],%d,%d,%d,%d", s.name,
&s.exam1, &s.exam2, &s.exam3, &s.exam4) == 5 )
{
s.average = (s.exam1 + s.exam2 + s.exam3 + s.exam4) / 4.0f;
printf("%s: average = %f\n", s.name, s.average);
while(fgetc(file) != '\n');
}
fclose(file);
}
return 0;
}
/* my output
jones: average = 2.500000
smith: average = 3.500000
john: average = 32.000000
catherine: average = 58.000000
*/
-
Code doesn't work
I tried your code on my compiler, but it doesn't work.:confused:
-
>I tried your code on my compiler, but it doesn't work.
How to Report Bugs Effectively
The example I posted used "test.txt", not "datafile.txt". Could this be why it doesn't work? Point taken, however: error messages in the code might have been helpful.
In your code, does the replacing %s with %[^,] work like you want?
-
Woops..sorry
I tried it on my computer at home and now it works. Thanks very much! =):)