read %s %s %d %d to struct from records.dat using fscanf

This is a discussion on read %s %s %d %d to struct from records.dat using fscanf within the C Programming forums, part of the General Programming Boards category; Hello folks, what i'm trying to do is to read data separated by whitespaces (' ', '\t') from file using ...

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    46

    read %s %s %d %d to struct from records.dat using fscanf

    Hello folks,
    what i'm trying to do is to read data separated by whitespaces (' ', '\t') from file using fscanf
    and put it into struct array
    here's a piece of code:
    Code:
    typedef struct
    {
      char id[4], name[20];
      int grade;
    }rec;
    ...
    rec recs [10]
    ...
    while(fscanf(f, "%[^ ]%[^ ]%d", recs[i].id, recs[i].name, &recs[i],grade)) 
    {
       printf("%s %s %d", recs[i].id, recs[i].name, recs[i].grade);
       i++;
    }
    it doesn't print it as it should.
    i know that the problem is in reading (in second arg of fscanf)...

    any ideas?

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    So what is the input, and what is the output? Also you messed up with "&reces[i],grade".


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Nov 2009
    Posts
    46
    ok, when I do
    Code:
           ....
           i=0;
    	while ( fscanf ( f, "%[^ ]%[^ ]%d", recs[i].id, recs[i].name,	&recs[i].grade )!=EOF) 
    
    	{
    
    		printf("%s %s %d\n", recs[i].id, recs[i].name, recs[i].grade);
    
    		i++;
    
    	}
    it prints so much garbage.... it like takes couple of seconds to print that garbage.
    And then it ends with segmentation fault on the line where while bracket closes...
    What could be the problem?

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,264
    Perhaps the input is too large to fit into the arrays.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Nov 2009
    Posts
    46
    Quote Originally Posted by laserlight View Post
    Perhaps the input is too large to fit into the arrays.
    record.dat
    ABC John 3
    DEF Jack 4


    not that large

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,264
    Well... to be on the safe side, I suggest that you define a function like this:
    Code:
    int readRec(FILE *fp, rec *record)
    {
        return fscanf(fp, "%3s %19s %d", record->id, record->name, &record->grade) == 3;
    }
    then you change the loop to:
    Code:
    for (i = 0; i < 10 && readRec(f, &recs[i]); ++i)
    {
        printf("%s %s %d\n", recs[i].id, recs[i].name, recs[i].grade);
    }
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Nov 2009
    Posts
    46
    hey thanx laserlight, it worked
    but i get
    ABCJohn John 3
    DEFJack Jack 4

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,264
    Sorry, I cannot duplicate that using what I suggested.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Nov 2009
    Posts
    46
    its strange, because when im printing only id's
    it prints
    ABCJohn
    DEFJack

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,264
    That implies that id is storing a string of length greater than 3 (i.e., buffer overflow), but that is impossible because I put in that length of 3 restriction in the format specifier to specifically prevent that.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Nov 2009
    Posts
    46
    yeah thats the thing, man
    also in struct it is already defined as char id[3]

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,264
    Quote Originally Posted by r00t
    also in struct it is already defined as char id[3]
    You correctly declared it as char id[4], actually. Unfortunately, that is of no help since it is possible to write beyond the array bounds, resulting in undefined behaviour.

    I suggest that you post the smallest and simplest compilable program that demonstrates the problem. Check that your input is correct as well.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Registered User
    Join Date
    Nov 2009
    Posts
    46
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    typedef struct
    
    {
    
    	char id[4], name[20];
    
    	int grade;
    
    }rec;
    int readRec(FILE *fp, rec *record);
    
    int main(void)
    
    {
        FILE *f;
    
        int i;
    
    	
    
        rec recs[10];
    
    
    
        f = fopen ("record.dat", "r" );
    
        if ( f == NULL )
    
        {
    
    	printf("Cannot open record file");
    
    	exit(1);
    
        }
    
        for (i = 0; i < 10 && readRec(f, &recs[i]); ++i)
        {
        	printf("%s %s %d\n", recs[i].id, recs[i].name, recs[i].grade);
        }
    
        return 0;
    }
    int readRec(FILE *fp, rec *record)
    {
        return fscanf(fp, "%3s %19s %d", record->id, record->name, &record->grade) == 3;
    }
    heres the working program
    hey you know what, my id was of length 3.... omg... i put 4, and its working.. my bad
    thanx a lot, laserlight

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,264
    Quote Originally Posted by r00t
    hey you know what, my id was of length 3.... omg... i put 4, and its working.. my bad
    Ah, so we could explain your earlier problem as: the name was overwriting the null terminator for the id, thus the id and name were printed as if they were concatenated when you only print the id.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. help with structs and malloc!
    By coni in forum C Programming
    Replies: 20
    Last Post: 09-14-2009, 06:38 PM
  2. Need help with linked list sorting function
    By Jaggid1x in forum C Programming
    Replies: 6
    Last Post: 06-02-2009, 03:14 AM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 04:00 PM
  5. what does this mean to you?
    By pkananen in forum C++ Programming
    Replies: 8
    Last Post: 02-04-2002, 03:58 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21