Search code examples
cstringmallocgetlinestrlen

Input returns the correct string but doesn't run the function


I have the following code:

bool get_command(char *cmd){
    char *cm = (char*)malloc(strlen(cmd));
    strcpy(cm,cmd);
    const char *tok = strtok(cm," ");
if(!tok)
    return false;

if(!strcmp(tok,"MULTIPLY"))
{
    printf("WORKING!\n");
    return true
}
....




int main(void){
  while(1){
    char *input = NULL;
    char buf[MAX_LINE_LENGTH] = {0};
    int read;
    size_t len;
    read = getline(&input, &len, stdin);
    if (-1 != read){
      printf("Input: %s\n", input);
      sprintf(buf, "%s", input);
      get_command(input);
    } else {
       printf("No line read\n");
   }
   free(input);
  }
 return 0;
}

When I run the code and input MULTIPLY it returns

input: MULTIPLY

TOKEN: MULTIPLY

However this doesn't print out the WORKING. Could anyone explain why this does not work as expected?


Solution

  • In your code, you need to change

    char *cm = (char*)malloc(strlen(cmd));
    

    to

    char *cm = malloc(strlen(cmd) + 1);
    

    to have space for terminating null character.

    The strlen() does not count the terminating null and if you don't allocate memory for holding the null during copying, you'll be facing memory overrun causing undefined behavior.

    As per the man page of strcpy()

    char *strcpy(char *dest, const char *src);

    The strcpy() function copies the string pointed to by src, including the terminating null byte ('\0'), to the buffer pointed to by dest. The strings may not overlap, and the destination string dest must be large enough to receive the copy.

    That said, as per the man page of getline()

    getline() reads an entire line from stream, storing the address of the buffer containing the text into *lineptr. The buffer is null-terminated and includes the newline character, if one was found.

    As your delimiter string does not include the \n, the token will have the \n into it. To avoid, do either of following

    • include \n in delimiter string
    • use strncmp() for comparison.
    • strip down the \n after taking the input.

    Also, please do no cast the return value of malloc().