1

I want to split a string by the comma and separate the first number in the string into its own new string, the rest of the string I want to keep together.

So far I have tried this by using strtok() and I can get the first number into its own string, but now I can't figure out how to keep the rest of the string together.

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

int main(int argc, char *argv[])
{

    char testStr[] = "1000,first,second,third,+abc";
    char *uidStr;
    char *restOfstr;
    int n;

    //This is wrong, I know, but I want to populate 
    //the rest of the string after the first comma
    //into a single string without the UID.
    uidStr = strtok(testStr, ",");
    while (n < 5)
    {
        restOfstr = strtok(NULL, ",");
        n++;
    }
    return 0;
}
anastaciu
  • 23,467
  • 7
  • 28
  • 53
ldd12345
  • 91
  • 5
  • 3
    add error-checking, validation, **indentation** -- `char *comma; int n = strtol(testStr, &comma, 10); printf("n: %d + rest is '%s'", n, comma + 1);` see https://ideone.com/TGR2V1 – pmg May 14 '20 at 16:16

4 Answers4

1

You can use strchr to find the first comma in the string.

Then using strncpy to get the number in the string.

The complete code:

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

int main()
{
    char *str = "1000,first,second,third,+abc";
    char *s = strchr(str, ',');
    if(!s)
       return -1;
    char num[10];
    strncpy(num, str, s-str);
    num[s-str] = '\0';
    int a = strtol(num, NULL, 10);
    printf("num = %d\nthe remaining: %s\n", a, s+1);
    return 0;
}
Hitokiri
  • 3,607
  • 1
  • 9
  • 29
1

strtok works fine, you have to keep in mind that it returns a pointer to each tokenized word so you need two pointers one for the first token and other for the rest of the string.

Demo

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

int main()
{
    char testStr[] = "1000,first,second,third,+abc";

    char *uidStr;       //pointer to uid
    char *restOfstr;    //pointers to the rest of the string

    uidStr = strtok(testStr, ",");  //uid remains in testStr
    restOfstr = strtok(NULL, "\n"); //rest of the string

    puts(uidStr); //or puts(testStr) to print uid
    puts(restOfstr); //print rest of the string

    return 0;
}

If you want a more secure function you can use strtok_s.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • i did not DV, but i think we do not need to split all of string. Because if the length of string is so long, we will waste time for splitting the rest of this string. – Hitokiri May 14 '20 at 17:15
  • @d4rk4ng31, yes, it has hapened and it will happen again, normally I don't give too much importance, but it's not in the spirit of the site, if one doesn't like an answer its nice to say why so the answer can be improved. – anastaciu May 14 '20 at 17:18
  • @anastaciu (also @OP), A look at the documentation was enough, instead of asking the question. – kesarling He-Him May 14 '20 at 17:29
  • @d4rk4ng31, indeed, but it's ok, it's a quirky function, a beginner might not be able to fully understand how to make it work. – anastaciu May 14 '20 at 17:34
  • 1
    Yep. I agree :) – kesarling He-Him May 14 '20 at 17:35
  • Does restOfstr have a null terminator? If I were to pass this as an argument how does it now when its hit the end of this string? – ldd12345 May 14 '20 at 19:31
  • @ldd12345, yes, strtok replaces the delimiter with a null terminator, in this case, `\n` will be replaced by `\0`. just as in `uidStr` the `,` is rplaced by `\0`. – anastaciu May 14 '20 at 19:34
0
#include <string.h>
#include <stdio.h>


int main(int ac, char **av) {

        while (--ac) {
                char *p = *++av;
                char *t = strtok(p, ",");
                char *r = strtok(NULL,"");
                printf("%s : %s\n", t, r);
        }
        return 0;
}

Note that the empty string "" passed to the second strtok means that it cannot find a deliminator, thus returns the rest of the string.

mevets
  • 10,070
  • 1
  • 21
  • 33
  • Umm... If I do `char* p = "1000, er,rt";`, then the function doesn't work... What am I missing? – kesarling He-Him May 14 '20 at 16:20
  • You would be attempting to modify a string literal; did you get bus error? Try char _p[] = "1000, er, rt", *p = _p; – mevets May 14 '20 at 16:23
  • `char* p = "1000, er,rt";` creates the string literal `"1000, er,rt"` and stores the address that points to the first character's position in the pointer p, the string literal is a constant and can't be changed, so assignment attempts will fail. You could do `char p[] = "1000, er,rt";` instead, which makes an array of length 12 and initializes it with the string `"1000, er,rt"`, and you would be able to make assignments. – isrnick May 14 '20 at 16:44
  • Thanks @isrnick. What I fail to understand is, why was `char *r = strtok(NULL,"");` needed? One could have simply done `char* r = p` – kesarling He-Him May 14 '20 at 17:00
  • Strtok removes redundant copies of delimiters; so if you want 1000,,,hello to yield "1000" and "hello", the strtok does this; otherwise, t + strlen(t) + 1, would give you the residual. – mevets May 14 '20 at 17:06
  • @d4rk4ng31 No, those two statements do not produce the same result. It is actually the `t` pointer in `char *t = strtok(p, ",");` that is not strictly necessary, since it will end up that `t == p`, so you could print `p` directly. – isrnick May 14 '20 at 17:33
  • I realised that late, and included it in my answer – kesarling He-Him May 14 '20 at 17:34
0

In addition to the excellent answers @mevets and @anastaciu have provided (I would go with these), this code will also work fine.

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

int main(int argc, char** argv) {
    char _p[] = "1000,Hey,There";
    char* str1 = strtok(_p, ",");
    char* str2 = strtok(NULL, "");
    return 0;
}
kesarling He-Him
  • 1,944
  • 3
  • 14
  • 39