Thread: Using fgets() to scan a data before a delimiter

  1. #1
    Registered User
    Join Date
    Dec 2014
    Location
    Philippines
    Posts
    20

    Using fgets() to scan a data before a delimiter

    Is it possible to fgets() the string (or word) only after a delimiter? I yes then how?


    Example:
    Code:
    printer, scanner, machine

    Also, how can I sscanf() a string with an indefinite number of sizes and assign it to only one variable?

    Example:
    Code:
    str = "I Love C programming 9000";
    sscanf(str, "%s %d", strvar, intvar);

    Thanks in advance!

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,060
    fgets() just reads lines delimited by \n.
    It only stops when
    - a \n is found
    - EOF is found
    - the buffer is full.

    It does NOT parse the data at all - that's for you to do later on.

    > sscanf(str, "%s %d", strvar, intvar);
    You could try something like this, in this particular case
    sscanf(str, "%[^0-9]%d", strvar, intvar);

    Scan sets (read the manual) allow simple classification of data to expect.
    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.

  3. #3
    Registered User
    Join Date
    Dec 2014
    Location
    Philippines
    Posts
    20
    I tried using "%[^0-9]". It works and it fixed my problem. But the program doesn't get the integer "intvar". It's value is always zero.
    And, May I know what is the function of format specifier %[^0-9] ?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,060
    I told you already, they're called scan sets - RTFM.

    As for your int not reading problem, post some actual code.

    Perhaps you forgot it's supposed to be &intvar.
    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.

  5. #5
    Registered User
    Join Date
    Dec 2014
    Location
    Philippines
    Posts
    20
    oh.. yes, I forgot it. Thanks! My problem has been solved now! Thank You Very Much!

  6. #6
    Registered User
    Join Date
    Dec 2014
    Location
    Philippines
    Posts
    20
    Hello again,
    I got more problems again regarding sscanf ();

    Here is an example text file:
    Code:
    65AMO125, 9
    I scanned and extracted the data using sscanf()
    Code:
    sscanf (stockChecks, "%s, %d", &stockChecks, &noOfStock);
    Also, I tried doing it in different ways:
    Code:
    fflush (stdin);
    fflush (stdout);
    sscanf (stockChecks, "%[0-z]s, %d", &stockChecks, &noOfStock);
    sscanf (stockChecks, "%[^,], %d", &stockChecks, &noOfStock);
    sscanf (stockChecks, "%[^,] %d", &stockChecks, &noOfStock);
    sscanf (stockChecks, "%s %d", &stockChecks, &noOfStock);
    The program seems to read the "stockChecks" correctly. But the value of "noOfStock" is always zero. What should I do?

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,778
    One of them works for me:
    Code:
    #include <stdio.h>
    
    int main(void)
    {
        const char *input = "65AMO125, 9";
        char stockChecks[9] = "";
        int noOfStock = 0;
        if (sscanf(input, "%8[^,], %d", stockChecks, &noOfStock) == 2)
        {
            printf("Success: '%s' and '%d'\n", stockChecks, noOfStock);
        }
        else
        {
            printf("Failure: '%s' and '%d'\n", stockChecks, noOfStock);
        }
        return 0;
    }
    I get:
    Code:
    Success: '65AMO125' and '9'
    I took the liberty of specifying the field width to be 8 instead of going with your original unbounded use of %[^,].
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Dec 2014
    Location
    Philippines
    Posts
    20
    I don't know why, but I copied your code in my IDE and compiled it using MinGW GCC 4.8.1. The result for me is failure.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,060
    How about
    Code:
        const char *input = "65AMO125, 9";
        char stockChecks[9] = "";
        int noOfStock = 0;
        int result = sscanf(input, "%8[^,], %d", stockChecks, &noOfStock);
        if ( result == 2 )
        {
            printf("Success: '%s' and '%d'\n", stockChecks, noOfStock);
        }
        else
        {
            printf("Failure: sscanf returned %d\n", result);
        }
    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.

  10. #10
    Registered User
    Join Date
    Dec 2014
    Location
    Philippines
    Posts
    20
    Okay, so I think here's the problem. The code works if I used the constant character pointer "input". But, if I replace the variable "input" with the character array used in the program, it will be failure. The character array was declared as strCode with a size of 9999 and initialized to "". User will input a code and the program will find the code from a txt file using fgets and strncmp. The collected data will be stored in strCode. When the program found the matched string, it will sscanf the strCode and separate the code from the integer number. But whenever I use sscanf() with strCode, it doesn't seem to read the variable correctly. Why? And how can I fix this?
    Last edited by Bryan_James; 12-24-2014 at 03:29 AM.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,060
    What did you actually type in (or read from a file)?

    If the input lacks a comma, or doesn't fit inside the allocated space for your strCode, then it will fail.
    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.

  12. #12
    Registered User
    Join Date
    Dec 2014
    Location
    Philippines
    Posts
    20
    Here is a sample data from file:
    Code:
    12345ABC, 9
    87321POI, 4
    70975MMN, 6
    Here's a code fragment on how I scanned it:
    Code:
    stockFile = fopen ("stockfile.txt", "r");
    while (strCode != NULL) {
    fgets (strCode, MAX_SIZE, stockFile); if (strncmp (stockChecks, strCode, 8) == 0) { break; } }
    int result = sscanf(stockChecks, "%8[^,], %d", strCode, &noOfStock); if (result == 2) { printf("Success: '%s' and '%d'\n", strCode, noOfStock); } else { printf("Failure: '%s' and '%d'\n", strCode, noOfStock); } getch();
    Last edited by Bryan_James; 12-24-2014 at 04:14 AM. Reason: Corrected the code

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,778
    Quote Originally Posted by Bryan_James
    I don't know why, but I copied your code in my IDE and compiled it using MinGW GCC 4.8.1. The result for me is failure.
    This indicates that something is wrong with my example, e.g., I used something that is compiler specific, or I posted code that is different from what I actually tested despite claiming that it works for me.

    Quote Originally Posted by Bryan_James
    Okay, so I think here's the problem. The code works if I used the constant character pointer "input". But, if I replace the variable "input" with the character array used in the program, it will be failure.
    This indicates that something is wrong with your mangling of my example, i.e., my example actually worked, but after you made a mess out of it, it didn't. When you make changes to example code and report failure contrary to someone telling you that it worked for them, you must post what exactly you tried. Otherwise, you give the impression that the person who told you that it works is mistaken at best, or a liar at worst.

    As such, I suggest that you post the smallest and simplest compilable program that demonstrates the problem. Do not just post a code snippet. Post an entire program, like what I did in post #7. Something that we can copy and paste as-is, compile, and see what is the problem that you've been describing. This way, if it works for us, it won't be because we made it work, and if it doesn't work for us, we can be reasonably certain that that is why it didn't work for you, and thus advise you how to fix it.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,060
    Code:
    fgets (strCode, MAX_SIZE, stockFile); if (strncmp (stockChecks, strCode, 8) == 0) { break; } }
    int result = sscanf(stockChecks, "%8[^,], %d", strCode, &noOfStock);
    No wonder you're having trouble.
    You're fgets writes to one buffer, and your sscanf reads from another.

    while (strCode != NULL)
    If strCode is an array, it will ALWAYS be non-NULL.

    Try
    while ( fgets(strCode, MAX_SIZE, stockFile) != NULL )

    But like I said, you need to sort out out variable usage (and perhaps better naming would help you in this respect).
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Scan for a specific data
    By Bryan_James in forum C Programming
    Replies: 1
    Last Post: 12-13-2014, 08:31 AM
  2. Replies: 3
    Last Post: 03-18-2012, 07:33 AM
  3. Read text file, scan and store data into variables?
    By wisdom30 in forum C Programming
    Replies: 8
    Last Post: 04-18-2011, 11:23 PM
  4. fgets reads byherself data
    By Phoenix_Rebirth in forum C Programming
    Replies: 5
    Last Post: 12-30-2005, 04:01 PM
  5. Scan data from file
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 05-12-2002, 07:52 AM