Search code examples
csocketsipc

weird output of spliting char array in C


I work on the server side Socket (use Telnet client) in Linux. Client is required to input a line in certain format: (1)command(GET/PUT/DEL), (2)key and (3)associated value (spaces to seperate in between). This key-value pair is later passed accordingly to the function(GET/PUT/DEL), which saves the data in the shared memory (keyValueStore).

I try to spilt the input into 3 parts, but there are wierd result in reading Token(2).

  • may I know the reason? any advices on how to change my code? (what i expected are key1, key2 )

Thanks!

enter image description here

int main() {

...
    char input[BUFSIZE]; // Client Daten -> Server
    int bytes_read; // Bytes von Client

...

        while (1) {

            int bytes_index = -1;
            while (1) {

                bytes_read = recv(cfd, &input[++bytes_index], 1, 0);
                if (bytes_read <= 0)  // Check error or no data read
                    break;

                if (input[bytes_index] == '\n') {
                    // Received a complete line, including CRLF
                    // Remove ending CR
                    bytes_index--;
                    if ((bytes_index >= 0) && (input[bytes_index] == '\r'))
                        input[bytes_index] = 0;
                    break;
                }
            }
            if (bytes_index > 0) {   // Check for empty line
                printf("%s\n", input);
                printf("bytes_index: %d\n", bytes_index);

                //get the first token
                token = NULL;
                token = strtok(input, " ");
                //walk through other tokens
                int i = 0;
                while (token != NULL) {
                    strcpy(&input[i++], token);
                    printf("Token: %d : %s\n",i, token);
                    token = strtok(NULL, " ");
                }
                // Check for client command

                if (strcmp(input, "QUIT") == 0)
                    break;
            }

Solution

  • The result of strtok() refers to the source buffer, so strcpy(&input[i++], token); invokes undefined behavior by performing copy between overlapped objects.

    In this case you should simply remove the line because the results of copy doesn't looks used.

    If you want to use the tokens in the future, you should store them in a different way. Storing the pointers to each tokens may work (until new data is read to input). It will be like this:

    char* tokens[BUFSIZE];
    
    while (token != NULL) {
        tokens[i++] = token;
        printf("Token: %d : %s\n",i, token);
        token = strtok(NULL, " ");
    }