#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void eat() // clears stdin upto and including \n OR EOF
{
int eat;while ((eat = getchar()) != '\n' && eat != EOF);
}
int main(){
printf("\n COMMAND : "); char cmd[21]=""; scanf("%20s",cmd);
if(strcmp(cmd,"shell")==0||strcmp(cmd,"sh")==0)
{
getchar(); // absorb whitespace char separating 'shell' and the command, say 'ls'
while(1)
{
printf("\n sh >>> "); // print prompt
char shellcmd[1024]=""; // str to store command
scanf("%1023[^\n]",shellcmd); eat(); // take input of command and clear stdin
if(strcmp("close",shellcmd)==0||strcmp("x",shellcmd)==0)
break;
else
system(shellcmd);
}
}
}
In the code, some anomalous behavior is occurring which I'm unable to catch.
Upon entering sh ls and pressing [ENTER], the expected response is:
scanf() stored sh in cmd[] and leaves ls\n in stdin.getchar() takes up the space.printf() prints \n sh >>> to Terminalscanf() stores ls in shellcmd[], leaves \n in stdineat() reads the \n from stdin, leaving it emptysystem("ls") is executedI.e. results should be like this:
COMMAND : sh ls
sh >>>
file1 file 2 file3 ...
sh >>> | (cursor)
BUT
What I get:
COMMAND : sh ls
file1 file2 file3 ...
sh >>>
sh >>> |
Apparently, the 2nd scanf() and shell() are executing before printf() , or at least that's my assumption.
What's amiss?
Compiled on Clang and GCC with cc -Wall -Wextra -pedantic and tested on bash on MacOS as well as Linux
As you can find in the man page:
If a stream refers to a terminal (as stdout normally does) it is line buffered
So you might experience a delay in seeing the message printed by printf whenever it doesn't contain a newline. On the other end, the previos message is displayed as soon as the leading newline of the next printf is sent.
Solutions:
Add a newline at the end your message printf("\n sh >>> \n");
Force the current buffer to be displayed even in absence of a newline by calling flush() function (fflush(stdout))
Change the current stdout buffering behavior with setvbuf() function
setvbuf(stdout,NULL,_IONBF,0);