0

I'm reading bytes from a socket and copying it into a char array.

char usrInputStr[256];
if ((rbytes = read(STDIN_FILENO, usrInputStr, 256)) < 0) {
    perror("Read error: ");
    exit(-1);
}
char finalStr[rbytes + 1];
memcpy(finalStr, usrInputStr, rbytes);

Now I allot an array on the heap and split the string into words and put each word in an array of char arrays. This is the code that does that.

char** currentTokens = (char**)malloc(sizeof(char*) * 256);
for(int i = 0; i < 256; i++) {
    currentTokens[i] = (char*)malloc(sizeof(char) * 256);
}

int sz = splitStrToArray(finalStr, currentTokens);

The definition of the splitStrToArray function is here,this works fine.

int splitStrToArray(char* str, char** arr) {
    int count = 0;
    char* buffer;
    int len = strlen(str);

    for (int i = 0; i < len ; ++i) {
        if(isspace(str[i])) {
            count++;
        }
    }

    int index = 0;
    buffer = strtok(str, " ");
    while(buffer != NULL) {
        memcpy(arr[index], buffer, strlen(buffer));
        index++;
        buffer = strtok(NULL, " ");
    }
    return count;
}

However when I compare this with user input it doest return zero and thus the two string don't match.

if(strncasecmp(currentTokens[0], "quit") == 0) {
    printf("quit" );
    breakTrigger = 1;
} else if(strcasecmp(currentTokens[0], "q") == 0) {
    printf("q");
    breakTrigger = 1;
} else {
    callback(currentTokens, sz, port);
}

I've checked currentTokens[0] and the word is correct. When the I try to take the return value of strcasecmp in an int and print it I get Segmentation Fault. I'm new to C, any help appreciated.

PC Luddite
  • 5,883
  • 6
  • 23
  • 39
Antithesis
  • 327
  • 2
  • 4
  • 17
  • 2
    Are you sure that `currentTokens[0]` is really correct: aren't there any extra characters, such as newline? – MikeCAT Oct 17 '15 at 00:48
  • when I printf currentTokens[0] it gives the correct output is what I meant. – Antithesis Oct 17 '15 at 00:49
  • 1
    What MikeCAT meant is that if `currentTokens[0]` is `quit`, then `printf("%s1\n", currentTokens[0]);` should print `quit1` rather than `quit` and `1` on separate lines. –  Oct 17 '15 at 00:51
  • @Antithesis terminating characters, newlines, tabs, spaces, etc are difficult to notice unless you are using a trick like Chrono mentioned. Try trimming the user input before and after the text which should get rid of such characters. – RisingSun Oct 17 '15 at 00:53
  • http://stackoverflow.com/questions/122616/how-do-i-trim-leading-trailing-whitespace-in-a-standard-way this question will probably be useful if you are working with user inputted data. – RisingSun Oct 17 '15 at 00:55
  • 1
    You can use [these functions](http://pastebin.com/GJYRp8g4) to assist in debugging, specifically the `print_escstr` function. All printable bytes other than the space character are printed normally, and the space character and non-printable bytes are printed with escapes of the form ``, where `XX` is a 2-character hexadecimal sequence representing a single byte. –  Oct 17 '15 at 02:00

1 Answers1

1

None of your strings are null-terminated so you have undefined behaviour throughout. Using memcpy to copy strings is almost never what you want.

You should consider using strdup, if available. Otherwise malloc and then strcpy.

In the particular case of finalStr, I see no good reason to perform the copy at all. Just read directly into it (and don't forget to null-terminate.) Alternatively, use the standard C library instead of the underlying posix layer.

rici
  • 234,347
  • 28
  • 237
  • 341