Thread: Looking for suggestions on how to use multiple delimters on a string

  1. #1
    Registered User
    Join Date
    Mar 2013
    Location
    chicago
    Posts
    7

    Looking for suggestions on how to use multiple delimters on a string

    Hello.. So this is my first post. I've browsed on here before, but now I decided to try and get some help instead of racking my brain, wasting time and getting nowhere in some cases. I've read all the rules and guidelines before posting.
    This is part of a bigger program im working on that deals with data structures, but I'm trying to figure out a way to tokenize a long file of purchases that is being read to my program. I rewrote the program to pinpoint my problem. I need to get the name, cost, item and quantity from this string. I figured out how to look for the cost, but what about the name and item(shirts)? How can I do this all in one loop because there are multiple strings and i'm gonna eventually send all the info to a data structure for each person(name)? I'm only asking about the tokenizing part, but this code works for the cost. Thanks!

    Code:
    int main(void)  {
        
    char myString[] = "Angela bought 9 shirts for $6 each." ;
    char * del = " " ;
    char * token ;
        
        // this token gets the cost for each string
        token = strtok(myString, del) ;            
                while(token!= NULL) {
                    if(token[0] == '$') {
                        token = strtok(token, "$") ;
                        printf("%s\n", token) ;
                    }
                    token = strtok(NULL, del) ;
                }
    }

  2. #2
    Registered User
    Join Date
    Mar 2013
    Location
    chicago
    Posts
    7
    maybe im approaching this the wrong way. instead of thinking how to do it all at once i should be making them separate functions and calling the functions in the loop? ill keep trying

  3. #3
    Registered User
    Join Date
    Mar 2013
    Location
    chicago
    Posts
    7
    okay so i made a function for each the cost, quantity and for the name and its working as im reading my files in. not sure how to approach the items(shirts) function. any suggestions? once i get these values it shouldn't be too hard to plug them into the array of structures i built. thanks to anyone that read the post whether they replied or not.

  4. #4
    Registered User hex_dump's Avatar
    Join Date
    Dec 2012
    Posts
    88
    Is your string always guaranteed to be in the same format as in your example? Where is this string coming from, the user, an external file, etc?
    Put another way will the tokens you are looking for always be in the same format? if not what sort of initial algorithm have you come up with to search each string?

  5. #5
    Registered User
    Join Date
    Mar 2013
    Location
    chicago
    Posts
    7
    here is part of the file im reading in.. so my algorithm i've come up with is to look for the first word(name,which i've done) and to look for the cost, which i used the dollar sign as the delimeter (as in the example i posted)only now i put that in a function as well. now i need to look for the items purchased (coats, books, shirts, meals). it took me all day to build the structure and get the functions to work while reading the file. my brain is a little fried on how to look for items. the main objective is to pull out(name,cost,items,quantity) so that i can stick them in a data structure that i built.

    Daniel paid $78 for each of 2 coats.
    Daniel paid $97 for each of 5 books.
    Kemal bought 3 shirts for $19 each.
    Daniel paid $89 for each of 4 coats.
    Daniel bought 2 coats for $95 each.
    Tristyn paid $43 for each of 3 meals.
    Last edited by twench; 03-19-2013 at 07:43 PM.

  6. #6
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by twench View Post
    here is part of the file im reading in...the main objective is to pull out(name,cost,items,quantity) so that i can stick them in a data structure that i built.

    Daniel paid $78 for each of 2 coats.
    Daniel paid $97 for each of 5 books.
    Kemal bought 3 shirts for $19 each.
    Daniel paid $89 for each of 4 coats.
    Daniel bought 2 coats for $95 each.
    Tristyn paid $43 for each of 3 meals.
    So your input is well formatted and all you really need is a loop reading in each line and 2 calls to sscanf() to get the 4 values. With basic error checking this should be about 10 lines.
    Is this enough help or do you need an example?

    Bye, Andreas

  7. #7
    Registered User
    Join Date
    Mar 2013
    Location
    chicago
    Posts
    7
    Quote Originally Posted by AndiPersti View Post
    So your input is well formatted and all you really need is a loop reading in each line and 2 calls to sscanf() to get the 4 values. With basic error checking this should be about 10 lines.
    Is this enough help or do you need an example?

    Bye, Andreas
    i have a loop and can read the lines fine. i have 3 functions that read the name, cost, and the quantity. i call each function while reading each line. im trying to make a function to read the items(shirts). while i slept last night i thought about using strcmp to get the items? does that sound right?... now that i run it, doesnt look like strcmp returns a string. an example ill be much appreciated.
    Code:
    token = strtok(myString, del) ;
            while(token != NULL) {
                if(strcmp(token, "shirts") == 0 ) {
                    token = strtok(myString, del) ;
                    printf("%s\n", token) ;
                }
                token = strtok(NULL, del) ;
            }

  8. #8
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Here's an example what I mean:
    Code:
    #include <stdio.h>
    
    int main(void)
    {
        int op1, op2, result;
        char line[100];
        while (fgets(line, sizeof(line), stdin) != NULL)
        {
             if (sscanf(line, "%d + %d = %d", &op1, &op2, &result) == 3)
                puts("Addition");
             else if (sscanf(line, "%d - %d = %d", &op1, &op2, &result) == 3)
                puts("Subtraction");
             else if (sscanf(line, "%d * %d = %d", &op1, &op2, &result) == 3)
                puts("Multiplication");
             else if (sscanf(line, "%d / %d = %d", &op1, &op2, &result) == 3)
                puts("Divison");
             else
                puts("Can't parse line");
        }
    
        return 0;
    }
    You can see how simple it is to parse well formatted input using a combination of fgets() and sscanf().

    Bye, Andreas

  9. #9
    Registered User
    Join Date
    Mar 2013
    Location
    chicago
    Posts
    7
    i wish i could understand the way that worked with what im trying to do.. looks alot easier. im still trying to get the strcmp to work to read the items. I need lots of practice with tokenizing. thanks for your reply

  10. #10
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    strcmp - C++ Reference

    I have no idea why you are thinking strcmp returns a string.

    I wish you luck; but, without having a hint of what you want from us.
    I know I can not help you. The sscanf is a easy solution if the input is like you posted.

    Tim S.
    Last edited by stahta01; 03-20-2013 at 05:46 PM.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  11. #11
    Registered User
    Join Date
    Mar 2013
    Location
    chicago
    Posts
    7
    i understand that strcmp doesn't return a string. i'm barely learning C and thought that maybe passing in a pointer to my function using strcmp would help but im giving up because i obviously dont know what im talking about. what im trying to do is read in a file with multiple purchases and tokenize each line to get name, item, quantity, and cost. when i get each value im going to send it into a data structure. i figured out how to make a function for name, cost, and quantity but stuck on figuring out how to get item from each line. the scanf looks easy enough im just trying to figure out how to use it to work in my program. i appreciate the feedback and sorry if im being a hassle.

  12. #12
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Let me start by saying I appreciate your first post here.

    - You mentioned that you've searched for answers
    - You read the rules
    - You cut your program down into a simplified example that demonstrated the problem
    - You clearly asked your question
    - You used code tags
    - You used decent indentation in the code

    So just for that, I'd like to say thanks!

    You were given the wisdom in post #8 about how "simple it is to parse well formatted input using a combination of fgets() and sscanf()."

    Based on the input you provided, your input is well formatted - but notice how it's different based on two possible scenarios.

    Code:
    Daniel paid $78 for each of 2 coats.
    [Name] ... [Cost] ... ... ... [Quantity] [Item]
    
    Kemal bought 3 shirts for $19 each.
    [Name] ... [Quantity] [Item] ... [Cost] ...
    You need to take these two possible scenarios into account. The "scanf()" family returns the number of items successfully read. So you can scan each string checking to see if it took all the arguments for the first scenario - if not, re-scan it while checking to see if it took all the arguments for the second scenario. If the input you provided is consistent, then any deviation from these two scenarios can be considered an error.

    Here is an example for you to study. Note how the return value of "sscanf()" is used, and how you can ignore unwanted input with the '*' symbol within the format specifiers (read more here):

    Code:
    #include <stdio.h>
    
    #define MAX_ELEMENTS   6
    #define MAX_STR_LEN  256
    
    const char *input[MAX_ELEMENTS] =
    {
        "Daniel paid $78 for each of 2 coats.",
        "Daniel paid $97 for each of 5 books.",
        "Kemal bought 3 shirts for $19 each.",
        "Daniel paid $89 for each of 4 coats.",
        "Daniel bought 2 coats for $95 each.",
        "Tristyn paid $43 for each of 3 meals."
    };
    
    int main(void)
    {
        char name[MAX_ELEMENTS][MAX_STR_LEN];
        int cost[MAX_ELEMENTS];
        int quantity[MAX_ELEMENTS];
        char item[MAX_ELEMENTS][MAX_STR_LEN];
        int i;
    
        for(i=0; i<MAX_ELEMENTS; i++)
        {
            /* fgets() the string */
            if(sscanf(input[i],"%s %*s %*c %d %*s %*s %*s %d %s",name[i],&cost[i],&quantity[i],item[i]) != 4)
                if(sscanf(input[i],"%s %*s %d %s %*s %*c %d %*s",name[i],&quantity[i],item[i],&cost[i]) != 4)
                    printf("\n Bad formatting!\n");
        }
    
        for(i=0; i<MAX_ELEMENTS; i++)
            printf("Name:  %s\nCost:  %d\nQuan:  %d\nItem:  %s\n\n",name[i],cost[i],quantity[i],item[i]);
    
        return 0;
    }

  13. #13
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by Matticus View Post
    Let me start by saying I appreciate your first post here.

    - You mentioned that you've searched for answers
    - You read the rules
    - You cut your program down into a simplified example that demonstrated the problem
    - You clearly asked your question
    - You used code tags
    - You used decent indentation in the code

    So just for that, I'd like to say thanks!
    +1

    Quote Originally Posted by Matticus View Post
    Here is an example for you to study. Note how the return value of "sscanf()" is used, and how you can ignore unwanted input with the '*' symbol within the format specifiers (read more here):
    I wouldn't use the "*" in this case. I would just write out the whole line like:
    Code:
    if(sscanf(input[i],"%s paid $%d for each of %d %[^.].",name[i],&cost[i],&quantity[i],item[i]) != 4)
    which makes is more readable IMHO. The last format specifier is "%[" to get rid of the period. It reads every character up to (but not including) the next '.'
    Similar for the second line.

    @twench: the *scanf() family is a powerful tool for reading formatted input thus it really pays off to study all it's possibilities.

    Bye, Andreas

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. cin >> string // multiple lines
    By msshapira in forum C++ Programming
    Replies: 7
    Last Post: 05-27-2009, 04:39 AM
  2. Splittig a string into multiple strings
    By Evenstevens in forum C Programming
    Replies: 7
    Last Post: 04-09-2009, 12:38 PM
  3. multiple lines in a string
    By Cpro in forum C++ Programming
    Replies: 9
    Last Post: 06-12-2008, 12:00 PM
  4. Replies: 9
    Last Post: 03-09-2008, 04:17 PM
  5. Replies: 4
    Last Post: 03-03-2006, 02:11 AM