0

I have a text containing a list of ip:port and I have a multi-threading program that splits them to IP and port separately I used strtok but it gives a lot of errors and problems and makes the program gets segmentation fault every time + it needs make to strdup char pointer which very annoying I used strchr but it only gives me the port but can't use it to extract the IP the goal is extract IP as a string and the port as integer and never gets segmentation failed whatever

example:

This is the start function of the thread

void* startthread() {
    do {
        char* proxy = "127.0.0.1:443";

        char* buffered = strdup(proxy);

        char* host = strtok(buffered,":");
        int port = atoi(strtok(NULL,":"));

        printf("%s:%d",host,port);
    }while(1);
}

gdb

Thread 8 "main" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff4a34700 (LWP 47410)]
__GI_____strtol_l_internal (nptr=0x0, endptr=endptr@entry=0x0,

Bodo
  • 9,287
  • 1
  • 13
  • 29
  • I'd simply do the following: Find the position of the `:` then copy everything before that into one array and everything after that into another. Since the format is fixed those two arrays can have automatic storage duration with fixed size as well – UnholySheep Oct 12 '22 at 14:47
  • Try use debugger – TheRyuTeam Oct 12 '22 at 14:47
  • and maybe sscanf is better? – TheRyuTeam Oct 12 '22 at 14:49
  • 1
    You might check if you can use [strtok_r](https://linux.die.net/man/3/strtok_r) or [strsep](https://man7.org/linux/man-pages/man3/strsep.3.html) instead. – Gerhardh Oct 12 '22 at 14:49
  • Does this answer your question? [Splitting a string by space in C](https://stackoverflow.com/questions/323285/splitting-a-string-by-space-in-c) – timrau Oct 12 '22 at 14:52

2 Answers2

3

One fairly simple way to handle this (that, in keeping with your tags) is compatible with both C and C++) would be to use sscanf:

char host[256];
int port;

sscanf(proxy, "%255[^:]:%d", host, &port);

But yes, strtok and multithreading is a lousy combination. Then agin, strtok and almost anything is a lousy combination.

I suppose to be complete, I need to point out that that the [^:] scan format depends on implementation defined behavior. In theory, an implementation is allowed to treat this literally--as meaning either ^ or :, rather than "anything except a colon"--but I know of only one implementation ever (Borland's compilers for MS-DOS) that did so, and it's long-since obsolete.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0

In this simple case you can replace strtok with strchr.

void* startthread() {
    do {
        const char* proxy = "127.0.0.1:443";

        char* buffered = strdup(proxy);
        if(buffered != NULL) {

            char* host = buffered;
            int port = 443; // or any useful default value

            char* colon = strchr(buffered, ':')
            if(colon != NULL) { // found?
                *colon = '\0'; // cut off port number from host or IP address
                port = atoi(colon+1); // I suggest to use strtol instead of atoi
            } // otherwise there is nothing to cut off, and use default port
            printf("%s:%d",host,port);

            free(buffered);
        } else {
            // handle error
        }
    }while(1);
}
Bodo
  • 9,287
  • 1
  • 13
  • 29