So I am reading a text file in this format:
ABC 51.555 31.555
DEF 23.445 45.345
I am trying to use fscanf() to parse the data, because this file could grow or shrink it needs to be dynamic in the way it loads hence why i used malloc and i also want to store it in the struct below. I think the issue is with a space or even possible not writing the whole format specifier right. Here is my code.
typedef struct data
{
char name[4];
char lat[7];
char lng[7];
}coords;
int main(int argc, char *argv[])
{
////////////CREATES FILE POINTER/////////
FILE* fp;
///////////CREATES MALLOC POINTER TO STORE STRUCTS/////////////
coords* cp;
//////////OPENS FILE//////////
fp = fopen(argv[1], "r");
/////////GET THE TOTAL AMMOUNT OF LINES IN THE FILE/////////
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
rewind(fp);
//////SKIPS FIRST LINE//////////
while(fgetc(fp) != (int)'\n')
{};
/////////ASSIGNS MEMORY THE SIZE OF THE FILE TO //////////
cp = malloc(sizeof(coords) * size);
//////////READS FILE AND STORES DATA///////
fscanf(fp,"%s[^ ] %s[^ ] %s[^\n]", cp->name, cp->lat, cp->lng);
printf("%s\n%lf\n%lf\n", cp->name, cp->lat, cp->lng);
fclose(fp);
return 0;
}
And yes I am aware I did not include the header files but I have got the right ones stdlib and stdio
UPDATE 1: I have tried both replies and I get this on my screen:
ABC51.555
0.000000
0.000000
How come the 51.555 has not gone to the next item in the struct? Thanks
///////////////////////////////////////////////////////////////UPDATE 2////////////////////////////////////////////////////////
Okay I have modified my code to do the following.
typedef struct data
{
char name[4];
char lat[6];
char lng[6];
}coords;
int main(int argc, char *argv[])
{
////////////CREATES FILE POINTER/////////
FILE* fp;
///////////CREATES MALLOC POINTER TO STORE STRUCTS/////////////
coords* cp;
//////////OPENS FILE//////////
fp = fopen(argv[1], "r");
/////////GET THE TOTAL SIZE OF THE FILE/////////
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
long lines = -1;
rewind(fp);
//////GETS TOTAL AMMOUNT OF LINES/////////
char c;
while(c != EOF)
{
c = fgetc(fp);
if(c == '\n')
{
lines++;
}
}
rewind(fp);
////////////SKIPS FIRST LINE//////////
while(fgetc(fp) != (int)'\n')
{};
/////////ASSIGNS MEMORY THE SIZE OF THE FILE TO //////////
cp = malloc(sizeof(coords) * size);
//////////READS FILE AND STORES DATA///////
printf("Lines of text read: %d\n", lines);
fscanf(fp,"%s %s %s[^\n]", cp[0].name, cp[0].lat, cp[0].lng);
printf("%s\n", cp[0].name);
fclose(fp);
return 0;
}
Now when i try to print cp[0].name; I get the whole of the first line with no space in, like this.
ABC51.55531.555
If i got print cp[0].lat; I get this.
51.55531.555
And when i print cp[0].lng; I get this.
31.555
Which is the only correct one, I can not understand this behaviour. Why is it behaving like this? all the posts suggest (As i first thought) that each %s in fscanf would put it in to its own variable not concatenate them. Not mater if i use the dot notation or the direct -> it still has the same result. Thanks :)
The format specifier
"%s[^
... attempts to read a whitspace delimited string, followed by the character[
and then the character^
. Since the string will always end at whitespace, the next character will always be whitespace, which won't match the[
, and none of the rest of the format specifier will match.ALWAYS check the return value of
fscanf
to make sure you read all the things you thing you did. If the return value is wrong, give a diagnostic.ALWAYS use field size limits when reading into fixed size string arrays.
So in your case what you want is: