last fgets in a loop never executes - c

I am trying to populate 2 arrays using fgets. For some reason, the last fget of the last loop iteration never executes.
For example, if num_inputs = 5, only 9 lines are read (instead of 10).
int num_imputs;
//read the number of inputs
scanf("%d", &num_imputs);
char secret_arr[num_imputs][8];//stores all the secrets
char encoded_message_arr[num_imputs][256];//stores all the encoded messages
for(int i = 0; i < num_imputs ; i++){
fgets (secret_arr[i],8, stdin);
fgets (encoded_message_arr[i],256, stdin);
}
This code works perfectly find if I hardcode num_inputs instead of reading it using scanf(). Can someone explain why this is happening?

You are missing a newline in scanf (assuming your input has an ENTER for the num_inputs data entry). Results in the first fgets actually storing an empty string as it stops when it sees the newline that was part of the num_inputs data entry.
Should be:
scanf("%d\n", &num_imputs);

Related

Getting newline before print statement - C

The runs stored by N batsmen of a cricket team is passed as the input to the program. The program must print the name of the batsman who scored the highest runs.
#include <stdio.h>
int main()
{
int n;
scanf("%d",&n);
int run[n],maxIndex=0;
char name[n][100];
for(int i=0;i<n;i++)
scanf("%[^,],%d",name[i],&run[i]);
for(int i=0;i<n;i++){
if(run[i]>run[maxIndex])
maxIndex=i;
}
printf("%s",name[maxIndex]);
return 0;
}
Input:
5
BatsmanA,45
BatsmanB,42
BatsmanC,12
BatsmanD,9
BatsmanE,78
Output:
BatsmanE
The issue is I'm getting a newline at first before the print statement. Like,
Output:
BatsmanE
The issue is I'm getting a newline at first before the print statement.
That is becasue %[^,] reads the prior line's left-over '\n' first.
scanf("%d",&n); reads the "5" and stores 5 into n. '\n' remains in stdin.
scanf("%[^,],%d",name[i],&run[i]); reads the "\nBatsmanA,45" and stores "\nBatsmanA" into name[0], then reads the ",", then reads "45" and stores 45 into run[0].
To read a line of user input, research fgets().
First of all, if you want to use scanf for string reading, you should make sure you can't get more characters than the string can handle. For that you can use width sub-specifier:
scanf("%99[^,],%d", name[i], &run[i]);
About the '\n' you got on the beginning of that string, that's because "%[^,]"
keeps it from the previous scanf, just add * that will read and discard that thing:
scanf("%*[\n]%99[^,],%d", name[i], &run[i]);
but as you can see, the format string becomes a lot less readable now...
Best thing would be if you just used "%99s" and rely on spaces instead of ',':
scanf("%99s%d", name[i], &run[i]);
now you just separate the values with space in the input and get the same result:
Input:
5
BatsmanA 45
BatsmanB 42
BatsmanC 12
BatsmanD 9
BatsmanE 78
but at that point I'd personally prefer just separating the format into 2 "scanfs":
scanf("%99s", name[i]);
scanf("%d", &run[i]);
And again, you will get the same result

Unable to run a piece of code to get different types of data from user in C [duplicate]

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.

Why is the first value of my char array 10?

I'm new to programming but I wanted to make a program that gets as input a number, (length) and then stores a series of a's and b's of said length. Finally it should output the numbers as the ascii numbers. (so 97 and 98)
I thought I should malloc a char array of the size length and then do a for-loop over it and print everything as an integer.
The problem is however that I get a value 10 as the value of the first letter.
Thanks a lot for any help!
int main()
{
int length;
scanf("%d", &length);
char *matrix = malloc((length + 1 ) * sizeof(char));
for (int i = 0; i < length; i++)
{
scanf("%c", &matrix[i]);
}
for (int i = 0; i < length; i++)
{
printf("\n%d", matrix[i]);
}
return 0;
}
When inputting 3 on the first line and aba on the next line, I get 10 97 98.
However I expected it to be 97 98 97. Why do I get a value of 10 in the first place of the array?
Use
scanf(" %c", &matrix[i]);
^^^^
instead of
scanf("%c", &matrix[i]);
^^
When the format starts with a blank all white spaces are skipped.
From the C Standard (7.21.6.2 The fscanf function)
5 A directive composed of white-space character(s) is executed by
reading input up to the first non-white-space character (which remains
unread), or until no more characters can be read.
10 is the ASCII code of the (white space) new line character '\n' that was present in the input buffer after you entered the length of the array.
The first scanf() with the format string %d leaves a newline in the input buffer.
What happens here, is that your terminal collects input one full line at a time, passing it to the program, and then the scanf() only reads the digits from the buffer, leaving the newline character there for the next scanf() to see. The same would happen if you entered 10 abc: the space, abc and the newline would be left there.
This mismatch is not something people usually expect, and it's one of the things that makes scanf() annoying. I would suggest using fgets() instead to first read a full line, matching what the terminal gives, and then parse the number from it with sscanf() or strtol() (or atoi()).
This cleans up the issue at the point where the first line is read, instead of passing it on to the next input function to handle. Otherwise all your input functions are tied together, if the next input would be for a whole line with possible white space, you'd need to know if you expect to clear a pre-existing newline or not. (You could also replace the later scanf("%c") with getchar(), not that that matters with buffering though.)
That said, the scanf("%c")/getchar() loop may still see newlines if you enter lines that don't have as many characters as the loop expects, so if you don't want to see them at all, filter them out.
So, something like this:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int length;
char linebuf[100];
fgets(linebuf, 100, stdin);
length = strtol(linebuf, NULL, 10);
char *matrix = malloc(length + 1);
for (int i = 0; i < length; i++)
{
matrix[i] = getchar();
}
for (int i = 0; i < length; i++)
{
printf("\n%d", matrix[i]);
}
printf("\n");
return 0;
}
(The obvious downside of fgets() is that you have to decide on a maximum length for the input line, allocate a buffer and call another function in addition to it.)

fgets( ) does not wait for user input? [duplicate]

I wrote the following code:
int N;
scanf("%d", &N);
int i;
for (i = 0; i < N; i++) {
char line[LINE_MAX];
if (fgets(line, LINE_MAX, stdin) != NULL) {
// do stuff with line here
printf("%c - %c\n", line[0], line[1]);
}
}
I have an input file which has the number of lines it has, and then that number of lines followed which I want to process. So I read in the number of lines into N. After that, I use fgets to get the line to be able to process it.
However, fgets does not seem to wait for a stdin the first time. I always get output of -, and then it waits for input. Meaning, the first iteration of the loop, it is not waiting for standard input at fgets and just prints out two empty characters separated by - as my printf does.
Why is that? How can I get fgets to wait for input each time? I feel like it is a threading issue.
You can place a call to fflush() just after the scanf() like this:
int N;
scanf("%d", &N);
fflush (stdin);
int i;
... (rest of code)...
So the newline character ges erased from the stdin buffer and the next fgets() will stop to ask for input.
As geekosaur said, you are not handling the newline left behind by scanf. You can modify your scanf format string to take it into account:
scanf("%d *[^\n]", &N);
*[^\n] says to ignore everything after your integer input that isn't a newline, but don't do anything with the newline (skip it).
Test program output:
emulawsk#cs:~/testing$ ./test2
3
13
1 - 3
26
2 - 6
59
5 - 9
It has nothing to do with threading. scanf() reads exactly what you ask it to; it's leaving everything else unread, notably the newline following the data. (You also aren't dealing with the possibility that the user didn't type what you intended.)
If you want to do line oriented input, use fgets(). Don't use scanf() and hope the system can magically intuit that you want to ignore what you didn't read.

fgets() not waiting for input

I wrote the following code:
int N;
scanf("%d", &N);
int i;
for (i = 0; i < N; i++) {
char line[LINE_MAX];
if (fgets(line, LINE_MAX, stdin) != NULL) {
// do stuff with line here
printf("%c - %c\n", line[0], line[1]);
}
}
I have an input file which has the number of lines it has, and then that number of lines followed which I want to process. So I read in the number of lines into N. After that, I use fgets to get the line to be able to process it.
However, fgets does not seem to wait for a stdin the first time. I always get output of -, and then it waits for input. Meaning, the first iteration of the loop, it is not waiting for standard input at fgets and just prints out two empty characters separated by - as my printf does.
Why is that? How can I get fgets to wait for input each time? I feel like it is a threading issue.
You can place a call to fflush() just after the scanf() like this:
int N;
scanf("%d", &N);
fflush (stdin);
int i;
... (rest of code)...
So the newline character ges erased from the stdin buffer and the next fgets() will stop to ask for input.
As geekosaur said, you are not handling the newline left behind by scanf. You can modify your scanf format string to take it into account:
scanf("%d *[^\n]", &N);
*[^\n] says to ignore everything after your integer input that isn't a newline, but don't do anything with the newline (skip it).
Test program output:
emulawsk#cs:~/testing$ ./test2
3
13
1 - 3
26
2 - 6
59
5 - 9
It has nothing to do with threading. scanf() reads exactly what you ask it to; it's leaving everything else unread, notably the newline following the data. (You also aren't dealing with the possibility that the user didn't type what you intended.)
If you want to do line oriented input, use fgets(). Don't use scanf() and hope the system can magically intuit that you want to ignore what you didn't read.

Resources