This question already has answers here:
strcmp on a line read with fgets
(6 answers)
Closed 3 years ago.
I'm currently building my own shell.
I managed to make ls function using scanf() and now I'm on cd. But I realized that cd has space between cd and file so I changed scanf() to fgets().
The space problem has been solved but another problem came out. Even though I typed correctly, the program won't work.
char command[MAX_LEN];
int result = 1;
char *pwd[MAX_LEN];
do {
printf("%s > ", getcwd(pwd, 100));
fgets(command, 100, stdin);
if(!strcmp("cd", command))
change_dir();
if(!strcmp("ls", command))
list_dir();
} while(strcmp("exit", command));
return 0;
What is wrong with my code? Can you please tell me why it's happening?
fgets reads up to size-1 chars (in your case 100-1 so 99) and places a '\0' at the end of the string, so when you type "ls" in stdin and hit enter, fgets will receive "ls\n" since enter creates a \n char, and the command will be "ls\n\0"
since the \0 indicates the end of the string we can ignore this here for now.
When you strcmp("ls",command), you are comparing "ls" with the string in command that ends before \0 so "ls\n" since "ls" and "ls\n" are not the same, it will fail.
As others already have said, you could either add \n to your compare strings, or remove the \n
since you may be planning to add more to the line after your cd or ls, you could look into string seperation e.g. with strtok()
Related
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 2 years ago.
This question might look stupid but I am not used to work with C and I'm losing my mind here not knowing what is wrong.
Basically what I want is to get a number from the user, then a string, the user may write whatever he feels like, I want to keep just the first caracter of that string.
My code is the following:
#include <stdio.h>
int main()
{
int b, n;
char frase [2];
scanf("%d", &n);
fgets(frase, 2, stdin);
puts(frase);
return 0;
}
My problem is, after the fgets the program stops, no matter what I have after it, it only stops, no error messages or anything. What is happening?
What is happening?
Your code will:
For an input 123 abc:
Store 123 in n, store the space in frase followed by a null byte. Then it will print that single space and end its execution with no errors.
For an input 123 Enter abc:
Store 123 in n and store in frase the newline character \n added to the buffer when you pressed Enter, followed by a null byte, next it will print that \n and end its execution with no errors.
So it doesn't just stop, it does what it's supposed to do.
What you shoud do, to make your code more robust, is to also parse the number with fgets, and convert it with sscanf or strtol:
int n = 0;
char buffer[20];
char frase[2];
fgets(buffer, sizeof buffer, stdin);
if(sscanf(buffer, "%d", &n) != 1){
//value not parsed
}
fgets(frase, sizeof frase, stdin);
puts(frase);
Using scanf to parse inputs is rarely, if ever, a good ideia.
The fgets is grabbing the newline character that is in the buffer after scanf reads the int. Putting a getchar() before your fgets should fix the problem.
This question already has answers here:
fgets doesn't work after scanf [duplicate]
(7 answers)
Closed 3 years ago.
I have recently been trying to do an exercise in c.
I want to read the input which is something like: "SET 0" (note that the actual text will be parsed later).
I tried fgets as it is like that:
char in[20];
//ok, this reads the first line, the first input is meant to be a number
scanf("%s",in);
if(isdigit(in[0])){
char array[]={'?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?'};
auto counter = atoi(in);
while(counter !=0){
fgets(in, sizeof(in),stdin);
For some reason, when i type eg "SET 0" and i am using fgets the in variable is empty(will print nothing).
I tried scanf but it will not read the number.
Any ideas/suggestions of what i can do?
Thanks in advance!
Do not mix fgets() with scanf() until you know why scanf()` is evil.
fgets() read the left over '\n' of the first line of user input which scanf() did not read.
This question already has answers here:
Removing trailing newline character from fgets() input
(14 answers)
Closed 3 years ago.
I have created a little script in C which displays text in a Linux console, but I found one problem - the script adds a line break at the end of text. I have no idea why, normally I should get line break after /n.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char buf[1024];
char txt[100];
printf("Insert a text: ");
fgets(txt, 100, stdin);
snprintf(buf, sizeof(buf), "echo '%s'", txt);
system(buf);
}
The structure of the code has to stay the same. I need to use system function and snprintf().
I want to make a few things clear. Right when I'm running this script the output looks like this:
root#test:/home# ./app
Insert a text: Hello
Hello
root#test:/home#
How can I remove this newline after Hello?
fgets consumes the \n character in the buffer which you press after entering data. Just add
txt[strcspn(txt,"\n")] = 0;
just after the fgets to replace the \n character at the end of txt with a NUL-terminator. The strcspn function, in your case, counts the number of characters in txt until a \n character. If no newline character is found, then it returns the length of txt(strlen(txt)).
BTW, you need to include string.h if you want to use this function:
#include <string.h>
The problem you're facing is related with how fgets() behave. As per the man page
char *fgets(char *s, int size, FILE *stream);
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer.
So, it reads and stores the trailing \n (newline) generated by pressing ENTER after the input into txt. If you don't want that \n to be present in txt, you need to remove that from the input buffer manually before printing the contents of txt.
You can use strchr() or strcspn() to find out the possible \n and replace that with \0 (null) to solve your issue.
This question already has answers here:
Is there any way to peek at the stdin buffer?
(3 answers)
Closed 9 years ago.
I want to write a function that would tell me if stdin buffer is empty.
So, here's the code:
int buff_empty()
{
char buffer[3];
fgets(buffer, 3, stdin);
if(strlen(buffer) > 1) return 0;
return 1;
}
but the problem is - I don't want fgets() to wait for my input. I'm using my own function to read, for example, an integer, and then check with this func is buffer empty (was more than one number put) or not.
Function works well, but when I read a number (read function reads just to white space, just like scanf()), it waits for one breakline(Enter?) more. Is there any way to solve it?
Thanks in advance!
Part of the problem is that you are kind of asking the program to read your mind. When it reads (or tries to read) from the input, and there's nothing there, how does it tell the difference between there being no more input and the input just hasn't been entered yet?
The normal solution is to put the input into a separate file, and look for the end-of-file to tell when there is no more input. So when the program tries to read the next number, it hits the end of file and knows that there isn't any more input.
Try reading up on the feof() function, or the possible return values of fgets().
So this is the code, its pretty simple, but why isn't the fgets prompted again after the first loop? and age is. (And weirdly it works with scanf("%s",&name_temp) but I need to grab other characters too like áéíóúÇ, spaces, so it would be better with fgets)
int menu_option = 0;
char name_temp[80] = "";
int age_temp = 0;
while(menu_option != 9){
//strcpy(name_temp,"");
printf("Type your name\n");
fgets(name_temp, 80, stdin);
printf("\nType your age\n");
scanf("%d", &age_temp);
}
(moved from the deleted answer)
Guys thanks for your answers, but I don't think you guys understood my question, test this code that I sent, and you will see that instead of appearing the thing in the Terminal for you to type, it is just ignored after the first while loop.
What I wanted is that after the first loop (while) it came back and asked again the name of the person and the person using the program would have to type again. but instead of that, after the first time of the loop, it just doesn't ask for you to type anything, the fgets is completely ignored.
please try the code and say what can I do.
I tried the freopen thing and did not work.
When I ran it, it did indeed print out "Type your name" each time through the loop, but did not wait for input, because it was getting the '\n' which the call to scanf left on the input stream. This is a common problem; one solution is to insert getchar(); at the bottom of the loop, to eat that newline.
fgets read a line, that is, it read stdin until \n character is reached.
scanf left the \n character into stdin.
Then, fgets read an empty line.
You should open stdin in binary mode. Use freopen(NULL, "rb", stdin) to do this.
See C read binary stdin for more details.