Help split simple string in c

Started by
10 comments, last by shadowisadog 10 years, 10 months ago

Hi,

I have to split simple string in c.


char readLine[7]; //Get from a file, Examples: "001:330", "01:330", "01:33", "333:01"
char num1[3];
char num2[3];
 
//How can I get for example num1="001", num2="330"

I am not good with char manupalation. Please help me how I can split with delimiter ":"

I think should be easy since I know the line from file can be at most 7 characters, and in above format, so I don't need to do any other handling.

Thanks for your help!

Advertisement

In C, you would use strchr from string.h to do that.

Simple implementation


char* strchr(const char* str, int ch)
{
    while(*str && *str != (char)ch) str++;
    return (*str == (char)ch ? str : NULL);
}

I don't know why it takes an int rather than a char as second argument ;)

Using char[3] for num1 and num2 is not good, you need to leave room for the '\0' terminator if you are going to use it as a null terminated string later on, so make them char[4] instead. EDIT: And readLine nees to be char[8] as well.

EDIT: Whoops, used str instead of ch in the return statement there, fixed now.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Perhaps this will help:

http://www.cplusplus.com/reference/cstring/strtok/

Yep, that's probably the best plan although since he is only looking for a single delimiter character it's easy to roll your own version using strchr. Looks a bit like homework so I didn't go into too much detail.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#include <stdio.h>
#include <string.h>

int divideAndRefer(char* base, char** num1, char** num2){
    char* delimiter = strchr(base, ':');
    if (delimiter != NULL){
        *delimiter = '\0';
        *num1 = base;
        *num2 = delimiter + 1;
        return 1;
    }
    return 0;
}

int divideAndCopy(char* base, char* num1, int sizeNum1, char* num2, int sizeNum2){
    char* delimiter = strchr(base, ':');
    if (delimiter != NULL){
        char former = *delimiter;
        *delimiter = '\0';
        snprintf(num1, sizeNum1, "%s", base);
        snprintf(num2, sizeNum2, "%s", delimiter+1);
        *delimiter = former;
        return 1;
    }
    return 0;
}

int main(void){

    char readLine[8] = "001:330";
    char* num1, *num2;

    divideAndRefer(readLine, &num1, &num2);

    printf("%s %s.\n", num1, num2);

    char readLine2[8] = "001:330";
    char num3[4], num4[4];

    divideAndCopy(readLine2, num3, sizeof(num3), num4, sizeof(num4));

    printf("%s %s %s.\n", readLine2, num3, num4);

    return 0;

}

First thing, you need 8 bytes to keep the string "001:330", since you need an extra for the '\0'.

I am not a fan of strtok, so here you have two functions that will do what you need. The first one will change the content of the readline, so you won't be able to use it anymore, but it is faster and uses less memory. The second will copy the content to other variables. You should probably study both of them and understand how they work, feel free to ask any part you don't understand.

Good luck.

Currently working on a scene editor for ORX (http://orx-project.org), using kivy (http://kivy.org).

thanks for your replies!

KnolanCross, I will study your way later.

For now I tried this:


    char *mcc;
    char *mnc;
    char readLine[8];
 
    sprintf( readLine, "310:030" );
 
    mcc = strtok(readLine, ":");
    mnc = strtok(NULL, ":");
 
    printf("Just testing: %s:%s\n", mcc, mnc);
 
    return 0;

Hope this is ok way of doing it.


I think should be easy since I know the line from file can be at most 7 characters, and in above format, so I don't need to do any other handling.

Even when you are certain that input will be correct, it's best to assume it may not be and do some checking.

thanks for your replies!

KnolanCross, I will study your way later.

For now I tried this:


    char *mcc;
    char *mnc;
    char readLine[8];
 
    sprintf( readLine, "310:030" );
 
    mcc = strtok(readLine, ":");
    mnc = strtok(NULL, ":");
 
    printf("Just testing: %s:%s\n", mcc, mnc);
 
    return 0;

Hope this is ok way of doing it.

I would rather see you use snprintf instead of sprintf. Also I am not a fan of using mcc and mnc as your variable names because they are not very descriptive and they look too similar to one another. Also LennyLen is correct in stating that you should check mcc and mnc for NULL to ensure that the string was correctly formatted.

Ewww I don't like strtok any more ;) It needs to allocate per thread local storage to be thread safe, and that (avoiding a race condition) seems to be optional from the documentation?

The point where the last token was found is kept internally by the function to be used on the next call (particular library implementations are not required to avoid data races).

Yikes-a-mundo

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Ewww I don't like strtok any more ;) It needs to allocate per thread local storage to be thread safe, and that (avoiding a race condition) seems to be optional from the documentation?

The point where the last token was found is kept internally by the function to be used on the next call (particular library implementations are not required to avoid data races).

Yikes-a-mundo

Perhaps my ignorance is showing, but is that really that big of a concern in this instance? I understand what you are saying, but musafir2007 did not mention multithreading and the use case seems very simple.

This topic is closed to new replies.

Advertisement