Thread: Entering and splitting string

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    16

    Entering and splitting string

    Hello. I have a problem trying to split and store specific string.
    When user enters: Name1 10, Name 2 15, Name 3 40 I have to split it and store Names and age for other actions - like name sorting. So I have the problem of how to split and store the information correctly.

    Code:
    char *buf=(char*)malloc(MAX);
        fflush(stdin);
        char data[MAX];
        char name_age[MAX];
        system("cls");
        printf("Enter name and age:\n");
        gets(buf);
        strcpy(data, buf);
        fflush(stdin);
        char delims[] = ", ";
        char *result = NULL;
        result = strtok(data, delims);
        while(result != NULL) {
            printf("Entered information: %s\n", result);
            result = strtok(NULL, delims);
        }
    Can you help me with this. I found the strtok() function and separated the string to:
    Name1 20
    Name2 30
    and so on

    but I can't figure out how to store the information and use it afterwards.

    I'll appreciate any help.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    fflush(stdin) is undefined - read FAQ.
    gets is unsafe. Use fgets instead.
    Last edited by Elysia; 12-15-2007 at 02:39 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Captain - Lover of the C
    Join Date
    May 2005
    Posts
    341
    You can strtok() it into
    Name1 20
    Name2 30
    and so on
    Then strtok() each of those into the names and ages.
    Don't use fflush(stdin);
    Also, system("cls"); is not secure
    Don't quote me on that... ...seriously

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    system itself is unportable (due to that it simply executes OS specific programs), and how to clear the screen is also covered in the FAQ.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Dec 2007
    Posts
    16
    Thanks for your replies, guys. But can you give me help about how to store the string I've split and post-split it? That's what I can't find out. I'm not so good at C, so I don't know what's the best way to store and use the stored string after that.

    If I split it to name / age I think I'll be able to get, for example, the average age or sort the names alphabetically.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    One way would be to use a pointer to keep track of the position in your buffer, then search for ' ' or ',' and from that, extract the strings using memcpy.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Captain - Lover of the C
    Join Date
    May 2005
    Posts
    341
    Here's some psuedocode of how I'd solve this problem:
    Code:
    struct PERSON
    {
        char name[MAX];
        int age;
    };
    
    /************* inside the main() function *************/
    char data[MAX], name_and_age[MAX];
    PERSON names_and_ages[MAX];
    // Get the input
    count = 0;
    while (GetMoreData(data, name_and_age))
    {
        names_and_ages[count] = SeparateNameAndAge(name_and_age);
        count++;
    }
    
    // The GetMoreData function:
    bool GetMoreData(char data[], char name_and_age[])
    {
        name_and_age = strtok(data, delim);
        // if strtok didn't work return false
    
        return true;
    }
    
    // The SeparateNameAndAge function
    PERSON SeparateNameAndAge(char name_and_age[])
    {
        PERSON person;
        // strtok the name: person.name
        // strtok and convert the age: person.age
        return person;
    }
    Don't quote me on that... ...seriously

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Declaring variables in the middle of a block is C99 and should be avoided in C89 programs. In addition, casting malloc() is generally a bad idea.

    Here's one way to do it, with sscanf().
    Code:
        char delims[] = ", ", *result = NULL;
        char name[MAX];
        int age;
        result = strtok(data, delims);
        while(result != NULL) {
            sscanf(result, "%s%d", name, &age);
            printf("Name: %s\tAge: %d\n", name, age);
            result = strtok(NULL, delims);
        }
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #9
    Registered User
    Join Date
    Dec 2007
    Posts
    16
    dwks, your code gave me strange result. Age was at the place of Name and for Age there were quite big numbers - like 2101215 and so.

    Brad0407, I'm trying currently to use your suggestion for solving the problem, but I don't know if I'll be able to work it out.

    That splitting just stops me... I'm unable to continue with the next processing.

  10. #10
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Yes, of course, sorry, I forgot to eliminate the space from the list of delimiters. Here's a full working example.
    Code:
    #include <stdio.h>
    #include <string.h>
    
    void splitname(char *string) {
        const char *delim = ",", *next;
        char name[BUFSIZ];
        int age;
    
        for(next = strtok(string, delim); next; next = strtok(NULL, delim)) {
            sscanf(next, "&#37;s%d", name, &age);
            printf("Name: \"%s\", age: %d\n", name, age);
        }
    }
    
    int main(void) {
        char data[] = "Joe 10, Sam 20, Tim 40, Buckministerfullerine 80";
    
        splitname(data);
    
        return 0;
    }
    Output:
    Code:
    Name: "Joe", age: 10
    Name: "Sam", age: 20
    Name: "Tim", age: 40
    Name: "Buckministerfullerine", age: 80
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  11. #11
    Registered User
    Join Date
    Dec 2007
    Posts
    16
    dwks, thank you very much! It works perfectly! That's exactly how it should work.

    Can you help me just e little bit? I know how to store the age in an array and how to sort it and so on, but how can I store the names and sort them too?

  12. #12
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Well, it's not that much different from dealing with ages (numbers). You have to use a multi-dimensional array, however, much like this:
    Code:
    int numberarray[ELEMENTS];
    char stringarray[ELEMENTS][MAX_STRING_LENGTH];
    And when sorting strings, you need to use strcmp() to determine which string comes "before" another string.

    Try it out, see what happens. Get the number (age) code working first, and it should be a simple modification.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  13. #13
    Registered User
    Join Date
    Dec 2007
    Posts
    16
    Ok, so I made
    Code:
    int ages[50];
    int c = 0;
    and in the for loop
    Code:
    ages[c] = age;
    After that, when I printf age it is ok, I use another for loop and it prints all the ages.

    I also created
    Code:
    char names[50][20];
    but I can't figure out how to fill it in. I understand that it must be
    Code:
    names[0][John]
    names[1][Mark]
    and I fill the number with c (like ages[c]), but don't know how to fill in the name.

  14. #14
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Use strcpy().
    Code:
    strcpy(names[c], the_latest_name);
    c ++;
    Or something like that.

    And don't forget to #include <string.h>.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  15. #15
    Registered User
    Join Date
    Dec 2007
    Posts
    16
    dwks, I appreciate your help very much. Thank you.

    I added a struct to keep the names and age, so I can easily display them after that.
    Tomorrow I'll try to make it read the data from a binary file/write the new data to a file, because it's over 02:00 AM over here.

Popular pages Recent additions subscribe to a feed