#1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2002
    Posts
    0
    Rep Power
    0

    Unhappy URGENT Quickie: fscanf a line from a file? Please help me, deadline in a few hours!


    Hi, I seriously need help here and I hope you can help me, thanks. I have to submit the file for marking soon, hope you would have a heart :)

    This is what I have in my program code, and mind you, I'm only a few hours old when it comes to file handling in C, so please correct me wherever I'm wrong...

    Variables:
    -----------------------
    FILE *guestAccounts;
    char guestID[15];
    char guestName[30];
    char guestAddress[60];
    int guestContact;
    char guestEmail[30];
    Input to file:
    -----------------------
    fprintf(guestAccounts,"%s/ %s/ %s/ %i %s/",guestID,guestName,guestAddress,guestContact,guestEmail);
    Output from file:
    -----------------------
    fscanf(guestAccounts,"%[^/]*%c %[^/]*%c %[^/]*%c %i*%c %[^/]*%c",guestID,guestName,guestAddress,&guestContact,guestEmail);
    Output (by printf) wanted (assuming that these were the values input earlier on):
    -----------------------
    guestID == "A1234567X";
    guestName == "John Doe";
    guestAddress == "18 Woodlake Salt Marsh Avenue Planet Mars"
    guestContact == "98765432"
    guestEmail == "johndoe@wherever.com"

    To put it frankly, I have no idea what these %[^/]*c are. I followed an example document and came out with this. And I don't know also why I need to use %s/ to input the strings(full names, with spaces).

    I know it's pathetic, but I'm begging for help here! :confused:

    Basically, I need to input guest details into a file (which it does fine, albeit with them trailing slashes) and then read them out later on.

    I would really appreciate your help.

    Cheers, Kai.

    Note: It has to be done in C and not C++, thanks.
  2. #2
  3. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,638
    Rep Power
    4247
    %[^/] means match all characters from the input which are not '/' (basically keep reading chars until you hit a '/') . * means read the next input and then discard the value (i.e. do not assign it to any variable in the argument list). So %*c means, read one character and then ignore the value (i.e. do not assign the value to any of the variable arguments in the fscanf function)

    You can find out more about the scanf family's (scanf, fscanf, sscanf etc.) format specifiers in the following links:

    http://home.earthlink.net/~ddruml/scanf.html
    http://www.eskimo.com/~scs/cclass/int/sx2f.html
    http://www.cplusplus.com/ref/cstdio/scanf.html

    Hope this helps
  4. #3
  5. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2002
    Posts
    0
    Rep Power
    0
    Originally posted by Scorpions4ever
    %[^/] means match all characters from the input which are not '/' (basically keep reading chars until you hit a '/') . * means read the next input and then discard the value (i.e. do not assign it to any variable in the argument list). So %*c means, read one character and then ignore the value (i.e. do not assign the value to any of the variable arguments in the fscanf function)

    You can find out more about the scanf family's (scanf, fscanf, sscanf etc.) format specifiers in the following links:

    http://home.earthlink.net/~ddruml/scanf.html
    http://www.eskimo.com/~scs/cclass/int/sx2f.html
    http://www.cplusplus.com/ref/cstdio/scanf.html

    Hope this helps
    hey what's up :)

    i submitted the work already, but still am a little curious at what it is. okay I get the slash part...but am lost at the * part.

    read one character and then ignore the value (i.e. do not assign the value to any of the variable arguments in the fscanf function)?? that's exactly what i read from reference files hehe.

    the program ended up fine, but with me having to settle for non spaced values (e.g. a name)...

    I actually did %[/^/]%*c hoping to enclose the full name (with spaces of course) with slashes and the variable value is represented by the ^ sign. (and of course the dummy text file was written as such, just can't retrieve it properly...)

    but i guess i learnt my lesson. to learn and implement classes (or at least typedef struct, whatever it is) so that i can dump a chunk of grouped and formatted info onto a single line.

    that's where i should be heading, right?

    cheers, and thanks a lot!
  6. #4
  7. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,638
    Rep Power
    4247
    Originally posted by lordkai


    i submitted the work already, but still am a little curious at what it is. okay I get the slash part...but am lost at the * part.

    read one character and then ignore the value (i.e. do not assign the value to any of the variable arguments in the fscanf function)?? that's exactly what i read from reference files hehe.

    let's say your code looks like this:
    Code:
    #include <stdio.h>
    int main() {
      FILE *fp;
      char name[100], sex[20];
      fp = fopen("test.txt", "r");
    
      fscanf(fp, "%s %s", name, sex);
      printf("name=%s\nsex=%s\n", name, sex);
      fclose(fp);
    
      return 0;
    }
    Assuming that your input file looks like this:
    Pink Panther/Male

    Run this code and your output will look like this:
    name=Pink
    sex=Panther/Male

    which is clearly the wrong thing. The problem here is that the fscanf function reads characters for the first %s until it hits a space and assigns what it has read to the first variable (hence name = "Pink"). Then it reads characters for the second %s until it hits a space or end of file and assigns those characters to the second variable (hence sex="Panther/Male"). To get around this problem of spaces, you would typically do something like this:
    Code:
    fscanf(fp, "%[^/] %s", name, sex);
    Run this code and the output will look like this:
    name=Pink Panther
    sex=/Male

    which is *almost* the right thing. The function reads characters upto the /, because of the %[^/] and assigns it to the first variable (hence name = "Pink Panther"). Then it reads the remaining characters to match the second %s and assigns them to the second variable (sex = "/Male"). All we have to do is eliminate the / character from the second variable.

    One way to do this is:
    Code:
    char tmp;
    ...
    ...
    fscanf(fp, "%[^/] %c %s", name, tmp, sex);
    Now tmp will get the '/' character because of the "%c". Now the output will look like:
    name=Pink Panther
    sex=Male

    which is the right thing. However, we needed to declare an extra variable only to remove the separating char (i.e. the '/'). If you don't feel like doing that you can also do:
    Code:
    fscanf(fp, "%[^/] %*c %s", name, sex);
    Now the %*c will cause fscanf read the '/' char, but won't assign it to any variable because of the *. So the output will read:
    name=Pink Panther
    sex=Male

    This is the same output as the previous code, except that it doesn't need the extra variable (char tmp).

    Hope this explanation make sense. :)
  8. #5
  9. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2002
    Posts
    0
    Rep Power
    0
    bravo!

    that was a super cool explanation! now i understand the "*" part and now i can probably redo the program...but alas, its already too late hehehe.

    aww well, but still it's hella cool to understand how it works, and even cooler to know that you are so very very helpfule, Scorps.

    very much appreciate it, you da man!

    cheers, kai.

IMN logo majestic logo threadwatch logo seochat tools logo