SSCANF help

This is a discussion on SSCANF help within the C Programming forums, part of the General Programming Boards category; Trying to convert this function from its current form (see attached attempt) , to a function that uses one line ...

  1. #1
    Registered User mattz's Avatar
    Join Date
    Nov 2001
    Posts
    52

    Unhappy SSCANF help

    Trying to convert this function from its current form (see attached attempt) , to a function that uses one line and sscanf to readin users text and inputs (bold, underlined,italics, textsize) and then pass to another function. Here is the function, untouched:void gatherWebPageText( webPageTextLine* lineArray )
    {
    char* ptr;
    char buff[BUFSIZ];
    short currentLine;
    currentLine = -1; /* Negative one because the do-while loop will increment to zero */

    do
    {
    currentLine++;

    /* Get the text for the line */
    puts(""); /* Blank line */
    puts("------------------------------------------------------------------------");
    puts("Please type the next line of text for the web page and then press enter.");
    puts(" If you would like a blank line simply press enter.");
    printf(" To finish entering lines press the '%c' character and press enter.\n",END_OF_INPUT);
    fflush(stdout); /* Needed before a fgets() */
    fgets( buff, BUFSIZ, stdin );

    ptr = gets(lineArray[currentLine].text);

    fflush(stdin);

    if ((ptr[0] != END_OF_INPUT) && /* Terminating character */
    (ptr[0] != '\0' )) /* blank line */
    {
    puts(""); /* Blank line */
    puts(""); /* Blank line */

    ptr = malloc( strlen(buff)+1 );
    strcpy(ptr, buff );

    /* Does the user want the entered line to be bold? */
    printf("Do you want to show this line in bold? (Enter 0 for 'NO' or 1 for 'YES'): ");
    fflush(stdout); /* Needed before a fgets() */
    fgets( buff, BUFSIZ, stdin );
    sscanf( buff, "%d", &getNumberInRange);
    lineArray[currentLine].isBold = getNumberInRange(0,1);

    /* Does the user want the entered line to be italicized? */
    printf("Do you want to show this line in italics? (Enter 0 for 'NO' or 1 for 'YES'): ");
    fflush(stdout); /* Needed before a fgets() */
    fgets( buff, BUFSIZ, stdin );
    lineArray[currentLine].isItalics = getNumberInRange(0,1);

    /* Does the user want the entered line to be underlined? */
    printf("Do you want this line to be underlined? (Enter 0 for 'NO' or 1 for 'YES'): ");
    fflush(stdout); /* Needed before a fgets() */
    fgets( buff, BUFSIZ, stdin );
    lineArray[currentLine].isUnderlined = getNumberInRange(0,1);

    /* How large a font does the user want to display the text? */
    printf("How large do you want the text? 1 (smallest) to 7 (largest): ");
    fflush(stdout); /* Needed before a fgets() */
    fgets( buff, BUFSIZ, stdin );
    lineArray[currentLine].textSize = getNumberInRange(1,7);
    }

    } while ((lineArray[currentLine].text[0] != END_OF_INPUT) &&
    ((currentLine+1) < MAX_WEB_PAGE_LINES));

    return;
    }

    And here is my about my fourth attempt on it:
    void gatherWebPageText( webPageTextLine* lineArray )
    {
    char buff[BUFSIZ];
    char* ptr;
    short currentLine;

    currentLine = -1; /* Negative one because the do-while loop will increment to zero */

    do
    {
    currentLine++;

    /* Get the text for the line */
    puts(""); /* Blank line */
    puts("------------------------------------------------------------------------");
    puts("Please type the next line of text for the web page and then press enter.");
    puts(" If you would like a blank line simply press enter.");
    printf(" To finish entering lines press the '%c' character and press enter.\n",END_OF_INPUT);
    fflush(stdout);
    fgets(buff, BUFSIZ, stdin);

    lineArray[currentLine].text = malloc( strlen(buff)+1 );

    sscanf( buff,"%d,%d,%d,%d,%s", getNumberInRange(0,1), getNumberInRange(0,1), getNumberInRange(0,1),
    getNumberInRange(1,7));
    ptr = gets(lineArray[currentLine].text);

    lineArray[currentLine].isBold = getNumberInRange(0,1);
    lineArray[currentLine].isItalics = getNumberInRange(0,1);
    lineArray[currentLine].isUnderlined = getNumberInRange(0,1);
    lineArray[currentLine].textSize = getNumberInRange(1,7);

    if ((ptr[0] != END_OF_INPUT) && /* Terminating character */
    (ptr[0] != '\0' ))
    break; /* blank line */


    /* Blank line */
    // puts(""); /* Blank line */
    /*
    // /* Does the user want the entered line to be bold? */
    // printf("Do you want to show this line in bold? (Enter 0 for 'NO' or 1 for 'YES'): ");
    // lineArray[currentLine].isBold = getNumberInRange(0,1);

    // /* Does the user want the entered line to be italicized? */
    // printf("Do you want to show this line in italics? (Enter 0 for 'NO' or 1 for 'YES'): ");
    // lineArray[currentLine].isItalics = getNumberInRange(0,1);

    // /* Does the user want the entered line to be underlined? */
    // printf("Do you want this line to be underlined? (Enter 0 for 'NO' or 1 for 'YES'): ");
    // lineArray[currentLine].isUnderlined = getNumberInRange(0,1);

    // /* How large a font does the user want to display the text? */
    // printf("How large do you want the text? 1 (smallest) to 7 (largest): ");
    // lineArray[currentLine].textSize = getNumberInRange(1,7);
    // }


    } while ((lineArray[currentLine].text[0] != END_OF_INPUT) &&
    ((currentLine+1) < MAX_WEB_PAGE_LINES));

    return;
    }

    Hopefully someone can help

    thanks,
    Mattz

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,699
    What exactly is the problem? Is it not scanning anything/just some of the input? I have had some quirky behavior from the scanf family of functions. Nowdays I fgets everything and convert to the appropriate data type...

    But what about the other aspects of the function? Are they working OK?

    Well as far as the scanning part, you could use/modify this function:

    Code:
    int GetNextInt(char *string,  int *next)
    {
     int len = strlen(string);
     char temp[len] ;
     int i, j = 0;
     int flag = 0;
     int result = 0;
    
    for(i = *next; i < len; i++)
       {
        if(isdigit(string[i]))
        {
           temp[j] = string[i];
           j++;
           flag = 1;
        }
    
        if(!isdigit(string[i]))
        {
          if(flag == 1)
           {
    
            temp[j] = '\0';
            break;
           }
        }
       }
    *next = ++i;
    
     result = atoi(temp);
     return result;
    }
    It will faithfully retrieve each int one-by-one.
    One thing though, remember to reset the second parameter (int *next) to zero when you start processing another string.

    int next = 0;
    char string[] = "Today's High Was 97, The Low Was 76.";
    int hi = 0, lo = 0;
    hi = GetNextInt(string, &next);
    lo = GetNextInt(string, &next);
    next = 0; // <--- reset, so ready for next string


    Notice you can easily modify this function to be a function which counts the ints in an input string...very useful for verifying input.

    I couldn't compile your code because there were data structures that I would have to define on my system so I can't say for sure but it looked like potential errors were present...
    I didn't quite grasp some of the coding style though...
    Code:
    bool fun(bool value)
    {
        return std::pow(std::exp(1), std::complex<float>(0, 1) 
        * std::complex<float>(std::atan(1)*(1 << (value + 2))))
        .real() > 0;
    }

  3. #3
    Registered User mattz's Avatar
    Join Date
    Nov 2001
    Posts
    52
    Thanks,
    This does help some. I just need to figure out how to get that sscanf to work with fgets etc.

    Mattz

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    fgets into a buffer
    sscanf on the buffer just like you would using 'scanf' to read from the console

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

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,699
    Right. First fgets(char *buf, int howlong, ?FILE *ptr?) the input and then apply sscanf (buf, "%i %d %d", num1, num2, num3).
    (Sscanf stands for "string-scanf", probably.) Anyway, that's how to extract it from a string supposing your scanfs are not somehow malfunctioning--- of course, how could I forget? Never use the fgets family of functions with the scanf family, whew and here I was trying to explain to you how to use fgets with sscanf! I think scanf inserts a newline in the stream of data causing fgets to retrieve the newline and not the string that was it's target.
    OK so nix that. Your choices are then to 1) use the fgets, gets, puts family of "string only" functions. The benifit of storing data intermediately as chars is that it is easily parsable and may hold hundreds of numbers along it's length. Alternately, an int will always be a single int, period. (Almost. Packing them into longs and such are exeptions of course.) 2) use the scanf, fscanf family of functions, which,with their variable arguments lists, when working properly are very useful too ...

    Interestingly, there is the more advanced possibility of storing all the choices on the bitfield of say a long int. So viewed as bits, the long 0100 1001 0010 0001 could store a yes/no choice answer on one bit, a four choiced answer on two bits, etc, etc. So that long could hold 32 yes/no answers! The catch is you have to shift the bits with logical and mathematic operators yourself, as there is no way to simply manipulate each bit directly...anyway, read a good book on that...
    Code:
    bool fun(bool value)
    {
        return std::pow(std::exp(1), std::complex<float>(0, 1) 
        * std::complex<float>(std::atan(1)*(1 << (value + 2))))
        .real() > 0;
    }

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You could use a single character for the flags if you wanted.
    They're pretty easy to use. Even easier would be to use a structure.

    #define BOLD 1
    #define ITALIC 2
    #define UNDERLINE 4

    #define ISSET(x,y) (!!((x)&(y)))
    #define SET(x,y) (x)|=(y)
    #define UNSET(x,y) (x)&=~(y)

    Pretty simple stuff.

    SET( flags, BOLD );
    UNSET( flags, ITALIC );

    if( ISSET( flags, UNDERLINE ) ) puts("Text is underlined.");

    NOTE: You don't actually need the !! in the 'ISSET' macro, I just use it to force a 1 or 0 value for true or false. Remember that any non-zero value is considered true, as only a zero value is considered false for truth checks in C.

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

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,699
    Wow that's amazing code! What book are YOU reading?
    Code:
    bool fun(bool value)
    {
        return std::pow(std::exp(1), std::complex<float>(0, 1) 
        * std::complex<float>(std::atan(1)*(1 << (value + 2))))
        .real() > 0;
    }

  8. #8
    Unregistered
    Guest
    I'm self-taught. I have a ton of books. I don't think I've fully read a single one of them, I just pick them up and read a bit here and there from time to time. Honestly, I rarely use books but for reference. Here's a good reference point for standard functions that I refer to quite a bit.


    Quzah.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sscanf and string handling question
    By ursula in forum C Programming
    Replies: 14
    Last Post: 05-30-2009, 02:21 AM
  2. Problem using sscanf fgets and overflow checking
    By jou00jou in forum C Programming
    Replies: 5
    Last Post: 02-18-2008, 05:42 AM
  3. Problems reading formatted input with sscanf
    By Nazgulled in forum C Programming
    Replies: 17
    Last Post: 05-10-2006, 12:46 AM
  4. sscanf question
    By Zarkhalar in forum C++ Programming
    Replies: 6
    Last Post: 08-03-2004, 07:52 PM
  5. sscanf (I think)
    By RyeDunn in forum C Programming
    Replies: 7
    Last Post: 07-31-2002, 08:46 AM

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