Thread: sscanf problem...help please!

  1. #16
    Fear the Reaper...
    Join Date
    Aug 2005
    Location
    Toronto, Ontario, Canada
    Posts
    625
    Didn't think so. Now you can do your stuff.
    Teacher: "You connect with Internet Explorer, but what is your browser? You know, Yahoo, Webcrawler...?" It's great to see the educational system moving in the right direction

  2. #17
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    and of course - it is possible to check the token whether it includes '.'

    then - decide whether it is integer... It still can be stored as float, but printed with %.0f format or converted to integer during the printing...

    Of cause it will require to store the flag isInteger for each value read...
    Or - if all value supposed to be positive - values to be pritnted out as integers can be stored as negetives to indicate this flag...

    maybe thre are even better solutions... It's upto you to decide what is suffitient for you...
    Last edited by vart; 10-27-2006 at 02:11 PM.
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #18
    Registered User
    Join Date
    Oct 2006
    Posts
    23
    here is the section of code I have.

    Code:
    int i=0;
    float fltread;
    float var_data[10][1800];
    
    while (fgets(s,sizeof(s),f)!=NULL) //read the lines of var data
    {
       while(sscanf(s,"%f",&fltread) != 0)
       {
          /*  an integer was read  */
          var_data[i] = fltread;
          i++;
       }							
    }
    I get a compilation error:
    cannot convert from 'float' to 'float [1800]'

    I don't know if I have the array sized properly. I sized it to hold up to 10 variables each having a maximum of 1800 data points. Does this look correct?

    I can't seem to fix it.

  4. #19
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I'm not sure why you feel the need to have such a large array, but it doesn't matter, you're still using it wrong. A two dimensional array is an array of arrays. Thus, if you want just one element of one of those arrays, you have to use both sets of [ ]. Like so:
    Code:
    var_data[ i ][ j ] = fltread;
    That says: "Place fltread in spot j of array i."


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

  5. #20
    Registered User
    Join Date
    Oct 2006
    Posts
    23
    Quzah,
    If I have 20 variables that I need to keep track of and each variable can have up to 1800 data points, how should I size the array. Can you explain? I greatly appreciate your help. Thanks!

  6. #21
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    What is datapoint?

    Do you mean you have to read up to 20 lines; each line can contain up to 1800 numbers?
    Do you really need to store them all or just the min/max/avg?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  7. #22
    Registered User
    Join Date
    Oct 2006
    Posts
    23
    The data format looks like this (except there can be up to 1800 data points
    (ie - 9 9.05 9.1 9.15 9.2 9.25 9.3 9.35 9.4 9.45...... ).

    time
    9 9.05 9.1 9.15 9.2 9.25 9.3 9.35 9.4 9.45 9.5
    9.55 9.6 9.65 9.7 9.75 9.8 9.85
    9.9 9.95 10 10.05 10.1 10.15 10.2 10.25 10.3
    10.35 10.4 10.45 10.5 10.55 10.6 10.65 10.7 10.75
    10.8 10.85 10.9 10.95 11 11.05 11.1 11.15 11.2
    11.25 11.3 11.35 11.4 11.45 11.5 11.55 11.6 11.65
    11.7 11.75 11.8 11.85 11.9 11.95 12 12.05 12.1
    12.15 12.2 12.25 12.3 12.35 12.4
    12.45 12.5 12.55 12.6 12.65 12.7 12.75 12.8 12.85 12.9 12.95 13
    13.05 13.1 13.15 13.2 13.25 13.3 13.35 13.4 13.45
    13.5 13.55 13.6 13.65 13.7 13.75 13.8 13.85 13.9
    13.95 14 14.05 14.1 14.15 14.2 14.25 14.3 14.35
    14.4 14.45 14.5 14.55
    14.6
    speed
    10.2519 10.2519 10.2519
    10.2392 10.2392 10.2392 10.2265 10.2265 10.2265
    10.2137 10.2137 10.2009 10.2009 10.1881 10.1881 10.1881 10.1753 10.1753
    10.1753 10.1753 10.1753 10.1753 10.1753 10.1625 10.1625 10.1625 10.1497
    10.1497
    10.1497 10.1368 10.1368 10.1368 10.1239 10.1239 10.1239 10.1239
    10.1111 10.1111 10.1111 10.1111 10.0981 10.0981 10.0981 10.0981 10.0852
    10.0852 10.0852 10.0852 10.0852
    10.0852 10.0723 10.0723 10.0723 10.0723
    10.0593 10.0593 10.0593 10.0464 10.0464 10.0464 10.0464
    10.0464 10.0204
    9.70302
    .
    .
    .
    more of the same


    Here is my revised code:

    Code:
    while (fgets(s,sizeof(s),fft)!=NULL) //read the lines of var data
    {
       while(sscanf(s,"%f",&fltread) != 0)
       {
          /*  a float was read  */
          var_data[v][z] = fltread;
          printf("var data = %f\n", var_data[v][z]);
          z++;
       }							
    }
    v++;
    When I loop through the data it only records the first value over and over again. So in the case of the first variable "time" it only records 9 over and over again. What am I doing wrong?

  8. #23
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by victor_miami
    Dave thanks for your reply. I fixed that problem. See earlier reply. I'm not looking for anyone to write my code for me. I need help figuring out which c lib functions are appropriate to solve the problems described below.

    My new problem is reading lines of data (see the most recent example I posted). The lines are all different...meaning the number of data points on each line varies (there could be only one, there could be as many as 15). The data is a mixture of real and integer numbers all separated by spaces, which may not be an issue since I would store them in a character array. Then I need to recognize when the data ends (the data is always ended by another variable followed by it's data.
    Sometimes I try to be a little subtle.

    I created an input file that combined both "sections" you posted (see attached file.txt). I was hoping you built and ran the code I posted (see my results in the attached results.txt). What I thought you ought to notice in the output is that only numeric values after PARAMS were printed. Which is to say that the code distinguished between numbers and text -- which was what I was attempting to show.

    Then you might then have discovered that the code that is used to distinguish the two is that call to strtod and subsequent error checking. By taking this bit out of the loop and using it in an if...else, you can handle numbers and text differently.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int foo(const char *filename);
    
    int main()
    {
       foo("file.txt");
       return 0;
    }
    
    int foo(const char *filename)
    {
       FILE *file = fopen(filename, "r");
       if ( file )
       {
          char line[BUFSIZ];
          int j = 0, reading = 0;
          while ( fgets(line, sizeof line, file) != NULL )
          {
             if ( reading )
             {
                int n;
                char field[20], *end, *text = line;
                while ( sscanf(text, "%19s%n", field, &n) == 1 )
                {
                   double value = strtod(field, &end);
                   if ( end != field && (*end == '\n' || *end == '\0') )
                   {
                      /* It's a number. */
                      j += printf("%s ", field);
                      if ( j > 72 )
                      {
                         j = 0;
                         putchar('\n');
                      }
                   }
                   else
                   {
                      /* It's not a number. */
                      putchar('\n');
                      puts(field);
                      j = 0;
                   }
                   text += n;
                }
             }
             else if ( strncmp(line, "PARAMS", 6) == 0 )
             {
                reading = 1;
             }
          }
          fclose(file);
          return 1;
       }
       else
       {
          perror(filename);
       }
       return 0;
    }
    And by the way, this does not care that the "variable name" text sits on a line by itself -- it could just as well be intermixed with the numbers.

    And again, in this example I am not storing anything. But notice that if you can print it, you can store it too.
    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. #24
    Registered User
    Join Date
    Oct 2006
    Posts
    23
    Dave,
    I'm sorry. I am a dummy for not recognizing the quality post. I will study the example you gave me and learn from it. I think I just reached a point of frustration and tiredness and was not being rational. Thanks again!
    Vic

  10. #25
    Registered User
    Join Date
    Oct 2006
    Posts
    23
    Dave,
    I used it and it worked as you said. Thanks! I have some questions as to some of the fields you implemented in the sscanf function.

    you used the following:
    Code:
     
    sscanf(text, "%19s%n", field, &n) == 1 )
    If you would please let me know what the "&n) == 1" is doing.

    I couldn't figure it out from the sscanf documentation in MS Dev C++ or on th enet. Maybe it was there and I'm not saavy enough to recognize it.

    Thanks!

  11. #26
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You must pass pointers to the *scanf functions, because it's the only way a function can change what's been passed. Thus, &n passes the address-of (the &) the variable n to the function.

    The == 1 is comparing the return value of the function to 1. Read the man page for a description of what the function returns, and what that means.


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

  12. #27
    Registered User
    Join Date
    Oct 2006
    Posts
    23
    Quzah thanks! What ever happened to "Hammer"? I don't see his/her posts any longer.

  13. #28
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Choose a copy of the standard.
    Quote Originally Posted by c99
    n No input is consumed. The corresponding argument shall be a pointer to signed integer into which is to be written the number of characters read from the input stream so far by this call to the fscanf function. Execution of a %n directive does not increment the assignment count returned at the completion of execution of the fscanf function. No argument is converted, but one is consumed. If the conversion specification includes an assignment suppressing character or a field width, the behavior is undefined.
    Hammer still visits fairly often, but he's busy.
    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. #29
    Registered User
    Join Date
    Oct 2006
    Posts
    23
    Dave,
    Thanks! Much appreciated.

  15. #30
    Registered User
    Join Date
    Oct 2006
    Posts
    23
    The "value" variable is a double (please see the code below). Is there a way to assign this to an array of float type variable? (i.e. - var_value[10][1600], where 10 can be up to 10 different variables and the 1600 can be 1600 pieces of data per variable). The reason I need to do this is that I am writing this out to a file and do not want it to appear as double precision. Or am I better off handling it when I write it to the file (at least I think there is a way to do this but I need to first figure out how).

    Thanks!


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int foo(const char *filename);
    
    int main()
    {
       foo("file.txt");
       return 0;
    }
    
    int foo(const char *filename)
    {
       FILE *file = fopen(filename, "r");
       if ( file )
       {
          char line[BUFSIZ];
          int j = 0, reading = 0;
          while ( fgets(line, sizeof line, file) != NULL )
          {
             if ( reading )
             {
                int n;
                char field[20], *end, *text = line;
                while ( sscanf(text, "%19s%n", field, &n) == 1 )
                {
                   double value = strtod(field, &end);
                   if ( end != field && (*end == '\n' || *end == '\0') )
                   {
                      /* It's a number. */
                      j += printf("%s ", field);
                      if ( j > 72 )
                      {
                         j = 0;
                         putchar('\n');
                      }
                   }
                   else
                   {
                      /* It's not a number. */
                      putchar('\n');
                      puts(field);
                      j = 0;
                   }
                   text += n;
                }
             }
             else if ( strncmp(line, "PARAMS", 6) == 0 )
             {
                reading = 1;
             }
          }
          fclose(file);
          return 1;
       }
       else
       {
          perror(filename);
       }
       return 0;
    }
    Last edited by victor_miami; 10-30-2006 at 01:16 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  2. problem with sscanf
    By nevrax in forum C Programming
    Replies: 19
    Last Post: 04-14-2007, 10:59 PM
  3. sscanf problem
    By LordShme in forum C Programming
    Replies: 5
    Last Post: 12-05-2006, 09:09 PM
  4. Weird problem with sscanf
    By g4j31a5 in forum C++ Programming
    Replies: 17
    Last Post: 10-04-2006, 09:16 PM
  5. Laptop Problem
    By Boomba in forum Tech Board
    Replies: 1
    Last Post: 03-07-2006, 06:24 PM