I am trying to write a Linux shell replacement for an operating systems class and am having trouble parsing the input strings. I am able to read in the very first line of a string input, but once it reaches any space delimiter, it completely skips everything else and proceeds to a new prompt. Below is the code I have for what I am trying to handle.
while(1){
//Flush I/O streams to prevent duplicate '#' printing each new line
fflush(stdout);
fflush(stdin);
printf("# ");
//Take in the input and store it in an auxiliary variable.
scanf("%s", input);
strcpy(commandInput, input);
char *ptr = strtok(commandInput, delimiter); //Parse the command and check what it is below.
if(strcmp(commandInput, "byebye") == 0){ //End the shell program
exit(1);
} else if(strcmp(commandInput, "whereami") == 0){ //Get the current working directory
getCurrentDirectory();
break;
} else if(strcmp(commandInput, "movetodir") == 0){
//Store the new directory name once returned
strcpy(currentDirectory, changeDirectory());
break;
} else {
//Handles any invalid input strings of any length
printf("%s\n", ptr);
while(ptr != NULL){
printf("%s\n", ptr);
ptr = strtok(NULL, delimiter);
}
}
}
As an example, below is the output I get when I input a random string that has a space between the tokens:
# hi there
hi
hi
# byebye
It should be printing out 'there' as well, but it never reaches it. Any help would be much appreciated!
As I mentioned [in my top comment], do not do fflush
on an input stream.
You are doing:
scanf("%s",input);
This will only get the first token on a given line. So, if the input line was (e.g.) hello world
, the scanf
will only put hello
into input
Replace with:
fgets(input,sizeof(input),stdin);
To account for the newline that fgets
leaves in the buffer, be sure that delimiter
is something like:
const char *delimiter = " \t\n";