Page 1 of 1

strcmp() and fgets() seem to not work with eachother.

Posted: Mon Jun 29, 2020 1:50 pm
by Flamore
Hi, i wanted to create some kind of shell for the ZX Spectrum but i found a problem later on,

Code: Select all

void obey_user(){
        cprintf("\n%s>", currentDisk);
        fgets(lastInput,25,stdin);
        if(strcmp(lastInput,"edit")==0){ // i also tried "strncmp(lastInput,"edit",25)" 25 is the maximum length 
                editor();
        }else{
                cprintf("\n?");
        }
}
Restraining the input to 5 characters seemed to do it.
Whatever i did it always would print "?".
I also did remove \n from the input using

Code: Select all

lastInput[strcspn(lastInput, "\n")] = '\0';
Is there something i did wrong? P.S googling didn't help.

Posted: Mon Jun 29, 2020 10:10 pm
by dom
The following works (fully compiling example):

Code: Select all

#include <conio.h>
#include <stdio.h>

static char lastInput[50];
static char *currentDisk = "a:";

void editor() {
        cprintf("In editor\n");
}

void obey_user(){
        cprintf("\n%s>", currentDisk);
        fgets(lastInput,sizeof(lastInput),stdin);
        if(strncmp(lastInput,"edit",4)==0){
                editor();
        }else{
                cprintf("\n?");
        }
}


int main() {
        while ( 1) {
                obey_user();
        }
}
As you spotted, fgets() terminates when return is pressed and places the \n into the buffer, so the buffer will be "edit\n\0". Likewise it terminates when n-1 characters are read (so your passing a length of 5 will cause the buffer to just contain "edit\0"

The strncmp example you provided will always fail since \0 ("edit\0") doesn't match \n ("edit\n\0") and hence it exit with nomatch.

I've just checked strcspn() and it does work as expected so I'm not sure why it didn't work for you.