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

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.

Related

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.

C How to get number of players and their names

Hi am trying to learn how to program and i would like the user to input how many players there are as well as their first names. i thought i was correct with my following code after watching some youtube videos and looking elsewhere online but i cannot see where i have gone wrong. if someone could please help that would be awesome.
int main() {
int i, player_num;
char names[8][25];
printf("\n\n");
//user inputs value of player_num, here, as you have now
for(i = 0; i < player_num; i++) {
printf("Enter the player's name: ");
scanf("%s", names[i]); //enters name and creates a newline <enter key>
getchar(); //removes the newline from the keyboard buffer
}
printf("\n\n");
for(i = 0; i < player_num; i++)
printf("\n%s", names[i]);
printf("\n\n\t\t\t press enter when ready");
getchar(); //holds the console window open until you press enter
return 0;
}
You want to enter the number of player. It seems that you have already written code for entering players name. So for entering number of Player you need to use one scanf()
int main()
{
int i, player_num;
char names[8][25];
printf("\n\n");
//user inputs value of player_num, here, as you have now
printf("Enter the number of player(from 1 to 8)\n");
scanf_s("%d",&player_num,sizeof(int));
for(i = 0; i < player_num; i++) {
printf("Enter the player's name: ");
scanf_s("%s", names[i],25); //enters name and creates a newline <enter key>
getchar(); //removes the newline from the keyboard buffer
}
printf("\n\n");
for(i = 0; i < player_num; i++)
printf("\n%s", names[i]);
printf("\n\n\t\t\t press enter when ready");
getchar(); //holds the console window open until you press enter
return 0;
}
Hope this Helps :)

scanf function not working with characters

I was just trying out a simple program in C, inserting into an array.
I used a scanf function to accept characters but it seems the compiler just skipped that and just went to end of the program.
This was the code that I used :-
#include <stdio.h>
void main()
{
int a[50], i, j, m, n, x;
char ch;
printf("Enter the no. elements of the array :- ");
scanf("%d", &m);
printf("Enter the elements below :- ");
for (i = 0; i < m; i++)
{
scanf("%d", &a[i]);
}
printf("The array is :- \n");
for (i = 0; i < m; i++)
{
printf("%d", a[i]);
}
printf("\nDo you want to enter an element ? (Y/N)\n");
scanf("%c", &ch); // The compiler just skips this along with the
while (ch == 'y' || ch == 'Y') // while loop and goes straight to the printf
{ // statement
printf("The index of the element :- ");
scanf("%d", &n);
printf("\nEnter a number :- ");
scanf("%d", &x);
for (i = m; i > n; i--)
{
a[i] = a[i - 1];
}
a[n] = x;
printf("\nInsert more numbers ? (Y/N)");
scanf("%c", &ch);
m = m + 1;
}
printf("\nThe array is :- ");
for (i = 0; i < m; i++)
{
printf("%d", a[i]);
}
}
I used the variable ch in order to allow the user to have a choice, whether or not to insert elements i.e. Y or N.
But the compiler basically skips the third scanf function, the one that accepts the char, along with the while loop.
I just want to know why the scanf function was skipped ?
Back to the previous scanf which is the last array member.
scanf("%d",&a[i])
In the input file if you entered:
32\n
^^
input will wait just before the newline after reading the decimal number.
In the scanf which causes problem:
scanf("%c", &ch);
It will read the newline character as it is available in input that's why it will skip that line after being executed implicitly.
To ignore the whitespace you have only to add space before the specifier %c as stated in comment by #xing and #WeatherVane.
scanf(" %c",&ch);
C99 7.19.6.2
Input white-space characters (as specified by the isspace function)
are skipped, unless the specification includes a [, c, or n
specifier.250)

fgets not waiting for user input

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);

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);
}
}

Resources