fgets not waiting for user input - c

In the given code fgets is not waiting for input.
I tried using scanf but it's giving unusual error(Exception thrown at 0x0F74DDF4 (ucrtbased.dll)). I'm using Visual Studio 2015 for debugging my code. Can anyone explain why fgets is not waiting for input?
#include<stdio.h>
#include<stdlib.h>
#include<process.h>
//GLOBAL-VARIABLE DECLARTION
#define MAX 1000
//GLOBAL-STRUCTURES DECLARATION
struct census
{
char city[MAX];
long int p;
float l;
};
//GLOBAL-STRUCTURE-VARIABLE DECLARATION
struct census cen[] = { 0,0,0 };
//USER-DEFINED FUNCTION
void header();
void header()
{
printf("*-*-*-*-*CENSUS_INFO*-*-*-*-*");
printf("\n\n");
}
//PROGRAM STARTS HERE
main()
{
//VARIABLE-DECLARATION
int i = 0, j = 0;
//int no_of_records = 0;
//FUNCTION CALL-OUT
header();
printf("Enter No. of City : ");
scanf_s("%d", &j);
printf("\n\n");
printf("Enter Name of City, Population and Literacy level");
printf("\n\n");
for (i = 0;i < j;i++)
{
printf("City No. %d - Info :", i + 1);
printf("\n\n");
printf("City Name :");
fgets(cen[i].city, MAX, stdin);
printf("\n");
printf("Population : ");
scanf_s("%d", &cen[i].p);
printf("\n");
printf("Literacy : ");
scanf_s("%f", &cen[i].l);
printf("\n");
}
//TERMINAL-PAUSE
system("pause");
}

When you enter the number of cities and press Enter, scanf doesn't read the linebreak character from input. fgets then tries to read but finds the linebreak, and immediately stops.
Don't use scanf to read numbers, use fgets to read in string first and then sscanf(or strtol/strtof/strtod) to convert to number.
char temp[LIMIT];
if(fgets(temp, LIMIT, stdin)) {
if(sscanf(temp, "%d", &j) == 1) {
// Ok
}
else {
// Handle sscanf error
}
}
else {
// Handle fgets error
}

I always use fgets followed by sscanf.
Declare this at the top,
char line[MAX];
Then use fgets to get a line, and sscanf to parse the int value out of it,
printf("Enter No. of City : ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &j);
Similar pattern for l
printf("Literacy : ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%f", &cen[i].l);

Related

String not scanned 2nd time when using gets function [duplicate]

This question already has answers here:
Using scanf and fgets in the same program?
(4 answers)
Closed 10 months ago.
When I am using gets function to scan item name in the first loop it runs properly but in the 2nd loop, it skips to Quantity quant without scanning item name.
I also tried using %s previously then it is working fine.
#include <stdio.h>
struct Dmart
{
char item[10];
int quant, price;
};
int main()
{
int i;
struct Dmart cust1[3], cust2[3];
printf("\nFor Customer 1\n");
for (i = 0; i < 3; i++)
{
printf("Item: ");
gets(cust1[i].item);
printf("Quantity: ");
scanf("%d", &cust1[i].quant);
printf("Price: ");
scanf("%d", &cust1[i].price);
printf("\n");
}
printf("\nFor Customer 2\n");
for (i = 0; i < 3; i++)
{
printf("Item: ");
gets(cust2[i].item);
printf("Quantity: ");
scanf("%d", &cust2[i].quant);
printf("Price: ");
scanf("%d", &cust2[i].price);
printf("\n");
}
printf("\nBill of Customer 1\n");
printf("Item\t\tQuantity\tPrice\n");
for (i = 0; i < 3; i++)
{
printf("%s\t\t%d\t\t%d\n", cust1[i].item, cust1[i].quant, cust1[i].price);
}
printf("\nBill of Customer 1\n");
printf("Item\t\tQuantity\tPrice\n");
for (i = 0; i < 3; i++)
{
printf("%s\t\t%d\t\t%d\n", cust2[i].item, cust2[i].quant, cust2[i].price);
}
return 0;
}
[VS Code Terminal Output][1]
The function gets is unsafe and is not supported by the C Standard. So do not use it.
The problem of the code is that after this call of scanf
scanf("%d", &cust2[i].price);
the new line character '\n' that corresponds to the pressed key Enter still is in the input buffer. So the next call of gets reads an empty string encountering at once the new line character.
Instead you could either always use the function fgets and then convert the entered string to an integer for integer data members of the structure or you can use scanf instead of gets like for example
for (i = 0; i < 3; i++)
{
printf("Item: ");
scanf( " %9[^\n]", cust1[i].item);
printf("Quantity: ");
scanf("%d", &cust1[i].quant);
printf("Price: ");
scanf("%d", &cust1[i].price);
printf("\n");
}
Pay attention to the leading space in the format string
scanf( " %9[^\n]", cust1[i].item);
^^^^
It allows to skip white spaces in the input buffer.

My C language program is giving a random space at the start and also generating one more serial number at the end

The program generates a blank space at the first line of the "data.txt" file and also generates a one more serial number.
#include<stdio.h>
#include<string.h>
int main(){
int limit;
int i = 0;
printf("How many approxmiate size of your list will be: \n");
scanf("%d", &limit);
char list[100][100];
FILE *store;
store = fopen("data.txt", "w");
while(i<=(limit - 1)){
printf("Enter task: \n");
gets(list[i]);
fprintf(store,"%s\n%d)",list[i], i+1);
i++;
}
fclose(store);
return 0;
}
It's because the linefeed ('\n') after scanf("%d", &limit); remains in the input buffer, either change scanf("%d", &limit); to scanf("%d ", &limit); or better yet, don't use gets() at all (it's dangerous to use gets(): read the reason here), instead use fgets() or scanf().
So your final code may look like this:
#include<stdio.h>
#include<string.h>
int main(){
int limit;
int i = 0;
printf("How many approxmiate size of your list will be: \n");
scanf("%d", &limit);
char list[100][100];
FILE *store;
store = fopen("data.txt", "w");
while(i<=(limit - 1)){
printf("Enter task: \n");
scanf(" %99[^\n]",list[i]);
fprintf(store,"%s\n%d)",list[i], i+1);
i++;
}
fclose(store);
return 0;
}

Output printed twice instead of once [duplicate]

I tried to execute the following simple code in ubuntu 15.10 But the code behaves odd than expected
#include<stdio.h>
int main(){
int n,i=0;
char val;
char a[20];
printf("\nEnter the value : ");
scanf("%s",a);
printf("\nEnter the value to be searched : ");
scanf("%c",&val);
int count=0;
for(i=0;i<20;i++){
if(a[i]==val){
printf("\n%c found at location %d",val,i);
count++;
}
}
printf("\nTotal occurance of %c is %d",val,count);
return 0;
}
output:
--------------------------
Enter the value : 12345678
Enter the value to be searched :
Total occurance of is 0
The second scanf to get the value to be searched seems not to be working. The rest of the code executes after the first scanf without getting input second time.
After first scanf(), in every scanf(), in formatting part, put a whitespace
So change this
scanf("%c",&val);
into this
scanf(" %c",&val);
Reason is, scanf() returns when it sees a newline, and when first scanf() runs, you type input and hit enter. scanf() consumes your input but not remaining newline, so, following scanf() consumes this remaining newline.
Putting a whitespace in formatting part makes that remaining newline consumed.
You can use fgets():
#include<stdio.h>
int main() {
int n, i = 0;
char val;
char a[20];
printf("\nEnter the value : ");
fgets(a, 20, stdin);
printf("\nEnter the value to be searched : ");
scanf("%c", &val);
int count = 0;
for (i = 0; i < 20; i++) {
if (a[i] == val) {
printf("\n%c found at location %d", val, i);
count++;
}
}
printf("\nTotal occurance of %c is %d", val, count);
return 0;
}
or clear stdin:
#include<stdio.h>
void clearstdin(void) {
int c;
while ((c = fgetc(stdin)) != EOF && c != '\n');
}
int main() {
int n, i = 0;
char val;
char a[20];
printf("\nEnter the value : ");
scanf("%s",a);
clearstdin();
printf("\nEnter the value to be searched : ");
scanf("%c", &val);
int count = 0;
for (i = 0; i < 20; i++) {
if (a[i] == val) {
printf("\n%c found at location %d", val, i);
count++;
}
}
printf("\nTotal occurance of %c is %d", val, count);
return 0;
}
Also, see C: Multiple scanf's, when I enter in a value for one scanf it skips the second scanf
printf("\nEnter the value : ");
scanf("%s",a);
printf("\nEnter the value to be searched : ");
scanf("%d",&val); // here is different
i don't know why, but code above working...
scanf("%d",&val);
You can use " %c" instead of "%c" for the format string. The blank causes scanf() to skip white space (including newlines) before reading the character.

Taking some string input from user with C

I am not too familiar with C syntax. I need to process some data based on user input. Although I processed the data successfully but I am stuck at user input section. I removed the unnecessary data processing section and made a simple example of how I am taking the user input. Can anyone tell me what's the problem with below code :
int i, number;
char *str;
str=(char*)malloc(1000*sizeof(char));
printf("Enter count : ");
scanf("%d", &number);
for(i=0; i<number; i++)
{
printf("\nEnter string: ");
scanf ("%[^\n]%*c", str);
printf("%s", str);
}
Output:
"Enter count : " appears fine, but whenever I provide some value and hit enter it's showing me only 'count' number of Enter string: without enabling user to enter the string.
For example -
Enter count : 2
Enter string:
Enter string:
But if I discard the count input section and provide any fixed value, like
for(i=0; i<5; i++)
it works fine
Thanks in advance
FYI, there is no issue in for(i=0; i<number; i++), problem is in scanning logic.
Actually, scanf ("%[^\n]%*c", str); is not right. you should use %s to read strings, not %c, which reads a single character, including the ENTER (newline).
Rather, i would suggest, use fgets() for inputs. It's a whole lot better in every way. Check the man page here.
Maybe you can use something like
//Dummy code
int i, number;
char *str;
printf("Enter count : ");
scanf("%d", &number);
str=malloc(number*sizeof(char)); //yes, casting not required
fgets(str, (number-1), stdin ); //"number" is used in different context
fputs(str, stdout);
EDIT:
Working code
#include <stdio.h>
#include <stdlib.h>
#define SIZ 1024
int main()
{
int i, number;
char * str = malloc(SIZ * sizeof (char));
printf("Enter the number :\n");
scanf("%d", &number);
getc(stdin); //to eat up the `\n` stored in stdin buffer
for (i = 0; i < number; i++)
{
printf("Enter the string %d :", (i+1));
fgets(str, SIZ-1, stdin);
printf("You have entered :");
fputs(str, stdout);
}
return 0;
}
scanf("%s",str); Use this instead of the code you are using to take string inputs in a character array.
There is a newline character \n after entering count value which is picked up by %c in your scanf()
Just use %s to scan strings as shown below.
scanf("%s",str);
If there are spaces in your input.
Then do
char c[50];
fgets(c,sizeof(c),stdin);
Check the below code:
#include <stdio.h>
#include<stdlib.h>
int main(){
int i, number;
char *str;
str=malloc(1000*sizeof(char));
printf("Enter count : ");
scanf("%d%*c", &number);
for(i=0; i<number; i++)
{
printf("\nEnter string: ");
fgets(str,1000,stdin);
printf("%s", str);
}
}

What is the best way to read a string?

So I'm really confused. I have to write a program in C which is basically an address book, thus I have to get multiple strings from the user (name, ID, phone etc.)
In the beginning I tried using scanf() only but it messed up sometimes with the newline character '\n'. After some googling, I ended up using scanf() for getting single chars or ints (where user answers yes or no questions, or chooses an action from a menu) and fgets() to read the fields of the address book. However, I also had to use fflush(stdin) multiple times after using scanf() which is not recommended here as I have seen. This method worked so far as intended.
So what's the optimal way to read a string from the user? Does fflush(stdin) not offer portability? This is an assignment so I have to think for portability too, since I will execute my code on another computer.
Thank you in advance.
EDIT: So here is what I've got so far. Excuse some words that are written in another language (Albanian). I believe you can understand what's going on.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void regjistrim();
void kerkim();
void modifikim();
void fshirje();
void rradhitje();
void display();
#define EMRI 50
#define MBIEMRI 50
#define ID 20
#define TEL 20
#define EMAIL 25
typedef struct addressbook
{
char emri[EMRI];
char mbiemri[MBIEMRI];
char id[ID];
char tel[TEL];
char email[EMAIL];
} addressbook;
FILE* Addressbook;
int main(void)
{
char input[2];
int choice;
printf("----------------ADDRESS BOOK----------------");
printf("\n\n\t1 - Regjistrimi i ri\n");
printf("\n\t2 - Kerkim\n");
printf("\n\t3 - Modifikim\n");
printf("\n\t4 - Fshirje\n");
printf("\n\t5 - Rradhitje\n");
printf("\n\t6 - Afishim i address book\n");
printf("\n\t0 - Exit\n");
fgets(input, 2, stdin);
sscanf(input, "%d", &choice);
while (choice < 0 || choice > 6)
{
printf("\nShtypni nje numer nga 0 - 6: \n");
fgets(input, 2, stdin);
sscanf(input, "%d", &choice);
}
switch (choice)
{
case 1:
regjistrim();
break;
case 2:
kerkim();
break;
case 3:
modifikim();
break;
case 4:
fshirje();
break;
case 5:
rradhitje();
break;
case 6:
display();
break;
case 0:
exit(0);
break;
}
return 0;
}
//Regjistron nje qytetar ne addressbook
void regjistrim()
{
char answer;
addressbook entry;
do
{
Addressbook = fopen("Addressbook.txt", "a+");
printf("\nShtypni emrin: ");
fgets(entry.emri, EMRI, stdin);
printf("\nShtypni mbiemrin: ");
fgets(entry.mbiemri, MBIEMRI, stdin);
printf("\nShtypni ID-in: ");
fgets(entry.id, ID, stdin);
printf("\nShtypni nr. telefoni: ");
fgets(entry.tel, TEL, stdin);
printf("\nShtypni email-in: ");
fgets(entry.email, EMAIL, stdin);
fprintf(Addressbook, "Emri: %sMbiemri: %sID: %sNr. telefoni: %sEmail: %s\n", entry.emri, entry.mbiemri, entry.id, entry.tel,entry.email);
fclose(Addressbook);
printf("\nShtypni y/Y neqoftese doni te regjistroni person tjeter: ");
fgets(answer, 1, stdin);
}
while(answer == 'y' || answer == 'Y');
}
With scanf, you can clear the newlines, like that. Also, I have included fgets too.
#include<stdio.h>
int main(void)
{
int i, N = 5;
char buffer[N];
printf("Enter %d characters\n", N+1);
scanf("%5s", buffer); /* MUST check comments below on this page for this! */
/* Clear trailing input */
while(getchar() != '\n')
/* discard */ ;
for(i = 0 ; i < 5 ; ++i)
printf("|%c|\n", buffer[i]);
printf("End with scanf\n\n");
/*****************************************************/
printf("Enter %d characters\n", N+1);
fgets(buffer, 5, stdin);
for(i = 0 ; i < 5 ; ++i)
printf("|%c|\n", buffer[i]);
printf("End with fgets\n\n");
return 0;
}
Also, this code demonstrates the limit you can put to every function for the input.
Source
Well "optimal" is maybe a bit subjective but I found
doing a separate function to read the number makes things
a bit easier and avoid scanf if you don't absolutely need it e.g.
int readNumber(int min, int max)
{
char number[32];
do
{
if ( fgets( number, sizeof(number), stdin ) != NULL )
{
// note that if 'number' is not a number atoi returns 0
int n = atoi(number);
if ( n>= min && n <= max )
{
return n;
}
}
printf( "please enter a valid value between %d and %d\n", min, max );
}
while ( 1 );
return -1; // never reached
}

Resources