fscanf function

This is a discussion on fscanf function within the C Programming forums, part of the General Programming Boards category; I am trying to read lines from a text file, but am having a few issues. To explain this better, ...

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    2

    fscanf function

    I am trying to read lines from a text file, but am having a few issues. To explain this better, I will give you 4 lines from the text file (the text files cannot be edited):


    [2007.12.17 07:17:19] df85f856d92472bd57d893701d7bb164 "H0TEL" "24.24.245.37" ACI-FILE-BLOCKER
    [2007.12.18 04:34:14] 0fdf1920b0e2c6efde8afd993f518c63 "Er wars" "89.245.217.83" ACI-MD5TOOL
    [2008.01.01 02:13:08] cfb78e7b36bd4efabb68daa3f49bfe62 "brn2kil" "69.133.113.154" ACI-KEYGEN
    [9999.99.99 99:99:99] zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz "zz" "999.999.999.999" END


    The 2 parts I really need scanned in, are the 32 character string and the part in quotes directly following it.

    Here is the code I am using to scan it:
    Code:
    while(year < 9999){
            fscanf(sensor1, "[%i.%i.%i %i:%i:%i] %s %s \"%i.%i.%i.%i\" %s\n", &year, &month, &day, &hour, &min, &sec, guid1, name, &ip1, &ip2, &ip3, &ip4, ban);
            fprintf(sensor2, "%s %s\n", guid1, name, ban);
            printf("%s - %i.%i.%i.%i\n", guid1, ip1, ip2, ip3, ip4);
    }

    sensor1 and sensor2 are file pointers and all the variables except guid1, name, and ban are ints. Those three are char arrays.

    When it reads the file above, the first line is read perfectly and prints:
    df85f856d92472bd57d893701d7bb164 - 24.24.245.37

    The second line is then read and it prints:
    0fdf1920b0e2c6efde8afd993f518c63 - 24.24.245.37
    That is not correct, the 32 character string is good, but the IP address is the same as the previous. Also the file that it is printing to looks like this:
    0fdf1920b0e2c6efde8afd993f518c6 "Er

    What I want it to do, for that second line, is print this on the screen:
    0fdf1920b0e2c6efde8afd993f518c63 - 89.245.217.83
    and this in the file:
    0fdf1920b0e2c6efde8afd993f518c6 "Er wars"

    So basically is there a way to allow anywhere from 0 to 8 spaces in a name?

    It also has trouble when the file hits the year 2008 for some reason. I'm thinking maybe because its date is like 2008.01.01 instead of 2008.1.1 .

    Any thoughts?

    Thank you

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    If you had examined the return value of fscanf, you would find that the second fscanf returns 8, meaning it matched 8 of the format specifiers, but then the format went bad. Once the format goes bad, nothing else gets read in. (Even on the next line, or anything.)

    In any event, %s does not read in anything with spaces in it, ever. You should look into the scanset specifier, turning those %s into something like \"%[^\"]\" or similar. (Unless you need the quotes or something.)

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    If the field(s) which could contain spaces are always the same, which they appear to be in your example, and they are always bracketed somehow (the first field with [], the third with ""), then you could use strtok and modify the delimiters this way:

    Code:
    #include <string.h>
    #include <stdio.h>
    
    int main (int argc, char *argv[]) {
    	char *tok, line[]="[2007.12.18 04:34:14] 0fdf1920b0e2c6efde8afd993f518c63 \"Er wars\"";
    	tok=strtok(line,"[]");
    	printf("%s\n", tok);        //2007.12.18 04:34:14
    	tok=strtok(NULL," ");
    	printf("%s\n", tok);       //0fdf1920b0e2c6efde8afd993f518c63
    	tok=strtok(NULL,"\"");
    	printf("%s\n", tok);     //Er wars
    }
    Obviously, you would have to apply fscanf to *tok at the appropriate point in order to extract your year.month.date from field 1, etc.

    Do read up on strtok if you haven't used it before, too.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,047
    scanset is the most likely way to go.
    Code:
    fscanf(sensor1, "[%i.%i.%i %i:%i:%i] %s \"%[a-zA-Z0-9 ]\" \"%i.%i.%i.%i\" %s\n", &year, &month, &day, 
        &hour, &min, &sec, guid1, name, &ip1, &ip2, &ip3, &ip4, ban);

  5. #5
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    I would also recommend reading in the entire line with fgets and then parsing it yourself with strtok or scanf.

    QuantumPete
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  6. #6
    Registered User
    Join Date
    Oct 2008
    Posts
    2
    Scanset worked perfectly.

    I am fairly new to the C language and haven't learned the scanset function. It seems like an invaluable tool. Thanks for the input!


    EDIT:
    BTW here is the resulting code.
    Code:
        while(ip1 < 999){
            fprintf(sensor2, "&#37;s %s %s\n", guid1, name, ban);
            printf("%s - %s - %i.%i.%i.%i\n", guid1, name, ip1, ip2, ip3, ip4);
            fscanf(sensor1, "[%[^\]]] %s \"%[^\"]\"  \"%i.%i.%i.%i\" %s\n", date, guid1, name, &ip1, &ip2, &ip3, &ip4, ban);    
        }

  7. #7
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,533
    I agree with QuantumPete.
    The line is so complex that should it fail, you've got a lot of work to try to figure out how to get back "in sync" with the input.
    Separating input from conversion makes for a simpler life IMO.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  2. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  3. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  4. Including lib in a lib
    By bibiteinfo in forum C++ Programming
    Replies: 0
    Last Post: 02-07-2006, 01:28 PM
  5. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM

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