Thread: Problem reading data from file and record it for use in program

  1. #1
    Registered User
    Join Date
    Apr 2005
    Posts
    7

    Question Problem reading data from file and record it for use in program

    Hey everyone,

    I have got a problem with reading data from a file and use it during the process of the program.

    I have a program that controls an interface card and that is working fine. At this moment I configure the settings in the code, but what I want is the possibility to set the configuration of the interface by using a file. I'm programming in C and use a Linux Kernel.

    The layout of the file will be as follow;

    # Standard network interface parameters
    DEVICE=sync0
    # Other media options are x21, v24 and v35
    MEDIA=x21
    # Network protocols are PPP, RAW or CISCO
    PROTO=RAW
    # We are a DCE and provide clock at the specified rate
    CLOCK=64000


    So what I want is that the code does something like this:

    when you find "DEVICE=" record the device name
    when you find "MEDIA=" record the media type (v24, v35, x21)
    when you find "PROTO=" record the proto type
    when you find "CLOCK=" record the clock speed


    After this it must be possible to use the recorded value's in other parts of the program.

    Only I don't now how to create this. Can someone help me!!
    Thanks for all your support.

    Allart

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    fgets will retrieve a line of text. An if statement will check if the first character is a # and therefore a comment. For lines which are not comments, a sscanf call will extract the property name and value into seperate variables.

  3. #3
    Registered User
    Join Date
    Apr 2005
    Posts
    7
    OK, thanks.
    I now know how to use fgets.
    Only how can I use sscanf to extract the property name and the value into seperate variables? I have search for some examples and I have read some tutorials, but don't know for sure. Can someone please explain me the best way to realise this. Maybee you can do this by using an example?

    Thanks for your support.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    184
    this is an example of how to use the sscanf(), here is sample code
    Code:
    #include<stdio.h>
    
    int main()
    {
        char str[20]={"hello world 2005"};
        char str1[10];
        int year;
        
        sscanf(str,"%s %*s %d",str1,&year);
        
        printf("%s -> %d",str1,year);
        
        getchar();
        return 0;
    }
    my output
    Code:
    hello -> 2005
    NOTE:
    Code:
     sscanf(str,"%s %*s %d",str1,&year);
    the const char "%*s" this means that read the data from the buffer but ingore it.(*)

    - s. s. harish

  5. #5
    FOX
    Join Date
    May 2005
    Posts
    188
    But the data in his in file is not separated by white space. How would you use sscanf on strings like these:
    Code:
    PARAM1=hello
    PARAM10=2600

  6. #6
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Code:
    #include <stdio.h>
    
    int main(void)
    {
       static const char filename[] = "file.txt";
       FILE *file = fopen(filename, "r");
       if ( file )
       {
          char line[80];
          while ( fgets(line, sizeof line, file) )
          {
             char key[40], value[40];
             if ( *line != '#' &&sscanf(line, "%39[^=]=%39[^\n]", key, value) == 2 )
             {
                printf("key = \"%s\", value = \"%s\"\n", key, value);
             }
          }
          fclose(file);
       }
       return 0;
    }
    
    /* my output
    key = "DEVICE", value = "sync0"
    key = "MEDIA", value = "x21"
    key = "PROTO", value = "RAW"
    key = "CLOCK", value = "64000"
    */
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  7. #7
    FOX
    Join Date
    May 2005
    Posts
    188
    What about a line like this:
    Code:
    const char *input = "       KEY1=val1    KEY2=val2     \t# comment"

  8. #8
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    "%*[ ]%39[^=]=%39[^ \t#\n]%n"
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  9. #9
    Registered User
    Join Date
    Jun 2005
    Posts
    1
    Could you explain this format a little bit? Is it a regular expression? Thanks.



    Quote Originally Posted by Dave_Sinkula
    "%*[ ]%39[^=]=%39[^ \t#\n]%n"

  10. #10
    FOX
    Join Date
    May 2005
    Posts
    188
    "%*[ ]" reads any amount of white space and discards it. You could change it to "%*[ \t]" if you want to detect tabs as well.

    "%39[^=]" reads at most 39 characters, until a '=' is detected. Which ever happens first.

    "=" Expect a '=' here to separate the key from val.

    "%39[^ \t#\n]" reads at most 39 characters until a blank, tab, '#' or newline is encountered.

    "%n" is the number of characters read so far. I don't know why he put it there since it's not needed.

  11. #11
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    >I don't know why he put it there since it's not needed.
    Code:
    #include <stdio.h>
    
    int main(void)
    {
       const char *input = "       KEY1=val1    KEY2=val2     \t# comment";
       char key[40], value[40];
       int n;
       while ( sscanf(input, "%*[ ]%39[^=]=%39[^ \t#\n]%n", key, value, &n) == 2 )
       {
          printf("key = \"%s\", value = \"%s\"\n", key, value);
          input += n;
       }
       return 0;
    }
    
    /* my output
    key = "KEY1", value = "val1"
    key = "KEY2", value = "val2"
    */
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  12. #12
    FOX
    Join Date
    May 2005
    Posts
    188
    How would you deal with a situation, where a configuration file allows lines to look like any of the following:
    Code:
    "KEY1=val1"
    "KEY1=val1  \t KEY2=val2 # Comment\n"
    "     \t\tKEY1=val1  \t KEY2=val2 # Comment\n"
    " KEY1=val1  \t KEY2=val2 \t KEY3=val3\n"
    "KEY1 = val1 # Comment\n"
    Basically, you want to filter an arbitrary amount of white space anywhere on the line, and stop reading a line when a '#' character is encountered. And you do not know how many key/val pairs are on each line either.

    The program should print an error message if input failure occurs.

  13. #13
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by ^xor
    How would you deal with a situation, where a configuration file allows lines to look like any of the following:
    Probably by writing a custom parser, looking for a regex package, or trying to rework the specification to have a tighter format.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  14. #14
    FOX
    Join Date
    May 2005
    Posts
    188
    > Probably by writing a custom parser, looking for a regex package, or trying to rework the specification to have a tighter format.
    %[...] doesn't support regex does it? From what I can tell, %*[ \t\n]%39[^=]...snip must match at least one tab, blank or newline in the beginning, so if you put KEY=val at the beginning of the line, that scan will fail?

  15. #15
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by ^xor
    > Probably by writing a custom parser, looking for a regex package, or trying to rework the specification to have a tighter format.
    %[...] doesn't support regex does it? From what I can tell, %*[ \t\n]%39[^=]...snip must match at least one tab, blank or newline in the beginning, so if you put KEY=val at the beginning of the line, that scan will fail?
    Code:
    #include <stdio.h>
    
    int main(void)
    {
       const char *input = "KEY1=val1";
       char key[40] = {0}, value[40] = {0};
       int n, items = sscanf(input, "%*[ \t]%39[^=]=%39[^ \t#\n]%n", key, value, &n);
       printf("items = %d, key = \"%s\", value = \"%s\", n = %d\n", 
              items, key, value, n);
       return 0;
    }
    
    /* my output
    items = 2, key = "KEY1", value = "val1", n = 1
    */
    Hmm.
    n [...]If the conversion specification includes an assignment suppressing character or a field width, the behavior is undefined.
    Bad me.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Data Structure Eror
    By prominababy in forum C Programming
    Replies: 3
    Last Post: 01-06-2009, 09:35 AM
  2. sequential file program
    By needhelpbad in forum C Programming
    Replies: 80
    Last Post: 06-08-2008, 01:04 PM
  3. Replies: 26
    Last Post: 06-15-2005, 02:38 PM
  4. Need help fixing bugs in data parsing program
    By daluu in forum C Programming
    Replies: 8
    Last Post: 03-27-2003, 06:02 PM
  5. Replies: 1
    Last Post: 09-30-2001, 07:45 AM