fflush(stdin) with VS2013 and VS2015 [duplicate] - c

I can't seem to figure out what's wrong with this code:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define MAX 100
#define TRUE 1
#define FALSE 0
char sect_cat;
char customer_name[MAX];
char customer_number[MAX]; /* error handling is easier */
int prev_unit = 0;
int current_unit = 0;
int consumed = 0;
int set = FALSE;
float init_bill;
float tax;
float total_bill;
void get_userinfo()
{
printf("Enter sector category: ");
scanf("%c", &sect_cat);
printf("Enter customer name: ");
fflush(stdin);
scanf("%sn", &customer_name);
set = FALSE;
while (set == FALSE)
{
printf("Enter customer number: ");
fflush(stdin);
scanf("%s", customer_number);
int i;
int error;
for (i=0, error=0; i<strlen(customer_number); i++)
{
if (isdigit(customer_number[i]))
{
}
else
{
error = 1;
}
}
if (error == 0)
{
set = TRUE;
}
else
printf("ERROR: Only numbers are allowed\n");
}
printf("Enter previous unit: ");
fflush(stdin);
scanf("%d", &prev_unit);
set = FALSE;
while (set == FALSE)
{
printf("Enter current unit: ");
fflush(stdin);
scanf("%d", &current_unit);
if (prev_unit > current_unit)
{
printf("ERROR: Current unit must be larger than previous unit\n");
}
else
set = TRUE;
}
consumed = current_unit - prev_unit;
}
int main()
{
/* Introduce program to users */
printf("\nThis program computes your electric bill based on these sector categories\n\n");
printf("\tResidential(R)\n");
printf("\tIndustrial(I)\n");
printf("\tCommercial(C)\n\n");
printf("Press any key to continue...");
fflush(stdin);
getchar();
#################### edit
Applying templatetypedef's solution, the program now waits for user input for the customer_name. However entering a string with a space leads to an error, and the program assumes that the word after the space is input for the next prompt.
Enter sector category: r
Enter customer name: George of the Jungle
Enter customer number: ERROR: Only numbers are allowed
Enter customer number: ERROR: Only numbers are allowed
Enter customer number:

The fflush function does not flush data out of an input stream; it is instead used to push data buffered in an output stream to the destination. This is documented here. As seen in this earlier SO question, trying to use fflush(stdin) leads to undefined behavior, so it's best to avoid it.
If you want to eat the newline from the return character entered when the user finished typing in their character, instead consider the following:
scanf("%c%*c", &sect_cat);
This will eat the newline rather than leaving it in stdin.
Hope this helps!

I think that you meant to write fflush(stdout) instead of fflush(stdin).

fflush should work with an output stream, see docs here

Related

How to print output on the same line as input?

How can I print on the same line as input?
This is my code
#include <stdio.h>
int main() {
int number;
printf("Enter number: ");
scanf("%d", &number);
printf("You entered: %d",number);
return 0;
}
What's happening:
Enter number: 23
You entered 23
What I want to achieve:
Enter number: 23 , You entered 23
Using the 'standard' input routines (those defined in <stdio.h>, such as scanf and getchar) will wait until you hit the "Enter" key before processing your input – and that "Enter" will be echoed as a newline (can't be avoided).
But you can use the getch() function (defined in <conio.h>); this will not echo the keys/characters you input so, when you hit "Enter", the newline is not 'reflected' on the console. However, you will then have to manually echo any other characters you type, and save them to an input buffer; you can then read your integer from that buffer using the sscanf function.
Here's a short example that does what you ask:
#include <stdio.h>
#include <conio.h>
#include <string.h>
int main()
{
char buffer[256] = ""; // Space for our input string
printf("Enter number: ");
int in;
while ((in = getch()) != '\r') { // Read until we see the "Enter" key ...
char out = (char)(in);
printf("%c", out); // We need to manually "echo" the input character...
buffer[strlen(buffer)] = out; // ... and add that to our input buffer
if (strlen(buffer) == 255) break; // Prevent buffer overflow!
}
int number;
sscanf(buffer, "%d", &number); // Read number from buffer ...
printf(" , You entered: %d", number); // ... and print it (on the same line)
return 0;
}
Note: There are more error-checks that you could (should) add to this code (like checking the return value of scanf to make sure a valid integer is given); however, what I have shown 'emulates' your original code, but without echoing the newline.

Program fails to receive second input

It's just a code to receive user inputs in C program, but fails to do so and accepts null space as input. I have tried fgets() as well and the same thing keeps happening. Please advice on how to fix.
#include <math.h>
#include <stdio.h>
//#include <string.h>
#define len 16
int main(void)
{
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int n,i=0,j=0;
printf("enter the number of cards:");
n = getchar();
//scanf("%d",&n);
int c1[len][n],card[len][n];
char buf[len];
printf("Enter card number:");
gets(buf);
system("Pause");
return (0);
}
"...code to receive user inputs in c program, but fails to do so and accepts null space as input..."
The reasons your existing code has problems is covered well in the comments under your post.
Consider a different approach: Define the following:
char inBuf[80] = {0};//
int numCards = 0;//Pick variable names that are descriptive (n is not)
int cardNum = 0;
bool isnum;
Then use it in conjunction with printf() etc.
printf("enter the number of cards:");
if(fgets(inBuf, sizeof(inBuf), stdin))//will read more than just a single char, eg. "12345"
{
int len = strlen(inBuf);
isnum = true;
for(int i=0;i<len;i++)
{
if(!isdigit(inBuf[i]))
{
isnum = false;
break;
}
}
if(isnum)
{
numCards = atoi(inBuf);
}
else
{
printf("input is not a number\n"
}
}
printf("Enter card number:");
if(fgets(inBuf, sizeof(inBuf), stdin))
{
...
Repeat variations of these lines as needed to read input from stdin, with modifications to accommodate assignment statements based on user input i.e. an integer (this example is covered), a floating point number, a string (eg. a persons name)
Although there is more that you can do to improve this, it is conceptually viable for your stated purpose...

scanf() to get in the string on the second time

What is wrong with the scanf() to get in the string on the second time, I can't input my string on the second time.
I am not sure with the error that occurs, I can't get this program function well
#include <stdio.h>
#include <stdlib.h>
int main()
{
//variables decleration
char staff_name1[31];
char staff_name2[31];
float sales1, sales2;
//input
printf("Enter staff name\t> ");
scanf("%[^\n]s", staff_name1);
printf("Enter sales amount\t> ");
scanf("%f", &sales1);
printf("\nEnter staff name \t> ");//ERROR,CAN'T INPUT MY STRING
fflush(stdin);
scanf("%[^\n]s", staff_name2);
printf("\nEnter sales amount\t> ");
scanf("%f", &sales2);
printf("\n");
//output
printf("Staff Name\t\t\t\tSales Amount\n");
printf("===================\t\t=============\n");
printf("%-20s \t%12.2f\n", staff_name1, sales1);
printf("%-20s \t%12.2f\n", staff_name2, sales2);
}
my output of this code is as below:
warning: this program uses gets(), which is unsafe.
Enter staff name > kh s
Enter sales amount > 134.14
Enter staff name >
Enter sales amount > 141243.14
Staff Name Sales Amount
=================== =============
kh s 134.14
141243.14
I can't input the second staff name. Can anyone please help me solve this??
fflush(stdin);
is undefined behaviour in standard C. To flush the newline character, you could simply use getchar() instead.
printf("\nEnter staff name \t> ");
getchar();
scanf("%[^\n]s", staff_name2);
I would also use fgets() instead of scanf to read a line and trim the newline if necessary, which offers better control over invalid inputs being entered by user and against buffer overflows.
You have three problems.
I see that you use %[^\n]s. It is wrong. The s isn't part of the %[ specifier. So use %[^\n] instead of %[^\n]s
After you enter the value for sales1, you press Enter. This character stays in the stdin(standard input stream). And when the next character for %[^\n] is \n, it will fail. Fix this problem by adding a space before %[^\n].
Using fflush on stdin invokes Undefined Behavior as per the C11 standard, although the behavior is well defined in some implementations. It is better to remove it so that your code will be more portable.
Additional notes:
You can limit the amount of characters to be scanned so that you can avoid buffer overflows.
You can check the return value of scanf to make sure it is successful. All the scanf in your program will return 1 on success.
Fixed Program:
#include <stdio.h>
#include <stdlib.h> //Unused header
int main()
{
char staff_name1[31];
char staff_name2[31];
float sales1, sales2;
printf("Enter staff name\t> ");
if(scanf(" %30[^\n]", staff_name1) != 1)
{
printf("Could not scan staff_name1");
return -1; //Exit main with a return value of -1
}
printf("Enter sales amount\t> ");
if(scanf("%f", &sales1) != 1)
{
printf("Could not scan sales1");
return -1; //Exit main with a return value of -1
}
printf("\nEnter staff name \t> ");
//fflush(stdin); UB!
if(scanf(" %30[^\n]", staff_name2) != 1)
{
printf("Could not scan staff_name2");
return -1; //Exit main with a return value of -1
}
printf("\nEnter sales amount\t> ");
if(scanf("%f", &sales2) != 1)
{
printf("Could not scan sales2");
return -1; //Exit main with a return value of -1
}
printf("\n");
//output
printf("Staff Name\t\t\t\tSales Amount\n");
printf("===================\t\t=============\n");
printf("%-20s \t%12.2f\n", staff_name1, sales1);
printf("%-20s \t%12.2f\n", staff_name2, sales2);
}

wrapper function in fgets()

I seek for an expert in c programming. Thanks in advance.
Example:
#include <stdio.h>
#include<stdlib.h>
#include<ctype.h>
void main()
{
char name[100][52],selection[2]="Y";
int x,nname=1;
float sales;
do
{
printf("Enter name: ");
fflush(stdin);
fgets(name[nname],51,stdin); // i need put a wrapper in here
printf("Enter sales: ");
scanf("%f",&sales);
if (sales<1000)
printf("%s\tgood\n",name[nname++]);
else
printf("%s\tvry good\n",name[nname++]);
printf("Enter another name?(Y/N)");
fflush(stdin);
fgets(selection,2,stdin);
*selection=toupper(*selection);
}while(nname<=100 && *selection=='Y');
for(x=1;x<nname;x++)
printf("%s\n",name[x]); // want print the result without(newline) /n
printf("END\n");
system("pause");
}
How do I print the names without being separated by new lines?
I compiled it with GCC 4.4.1 - MinGW and it works fine.
It launched only a warning. This is the result:
warning: return type of 'main' is not 'int'|
||=== Build finished: 0 errors, 1 warnings ===|
Now it works as you expect.
#include <stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include <string.h> // strlen()
void main() {
char name[100][52],selection[2]="Y";
int x,nname=1;
float sales;
do {
printf("Enter name: ");
fflush(stdin);
fgets(name[nname],51,stdin); // i need put a wrapper in here
for (x=0; x<strlen(name[nname]); x++){ // this will discarge the \n
if (name[nname][x] == '\n')
name[nname][x] = '\0';
}
printf("Enter sales: ");
scanf("%f",&sales);
if (sales<1000)
printf("%s\tgood\n",name[nname++]);
else
printf("%s\tvry good\n",name[nname++]);
printf("Enter another name?(Y/N)");
fflush(stdin);
fgets(selection,2,stdin);
*selection=toupper(*selection);
} while(nname<=100 && *selection=='Y');
for(x=1; x<nname; x++)
printf("%s ",name[x]); // want print the result without(newline) /n
printf("\nEND\n"); // inserted \n before END
system("pause");
}
Just use
printf("%s ", name[x]);
instead of
printf("%s\n", name[x]);
The \n character is creating the new lines.
Edit
fgets apparently reads newlines into the buffer - you can strip the newline with
name[nname][strlen(name[nname])-2] = '\0';

fflush(stdin) function does not work

I can't seem to figure out what's wrong with this code:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define MAX 100
#define TRUE 1
#define FALSE 0
char sect_cat;
char customer_name[MAX];
char customer_number[MAX]; /* error handling is easier */
int prev_unit = 0;
int current_unit = 0;
int consumed = 0;
int set = FALSE;
float init_bill;
float tax;
float total_bill;
void get_userinfo()
{
printf("Enter sector category: ");
scanf("%c", &sect_cat);
printf("Enter customer name: ");
fflush(stdin);
scanf("%sn", &customer_name);
set = FALSE;
while (set == FALSE)
{
printf("Enter customer number: ");
fflush(stdin);
scanf("%s", customer_number);
int i;
int error;
for (i=0, error=0; i<strlen(customer_number); i++)
{
if (isdigit(customer_number[i]))
{
}
else
{
error = 1;
}
}
if (error == 0)
{
set = TRUE;
}
else
printf("ERROR: Only numbers are allowed\n");
}
printf("Enter previous unit: ");
fflush(stdin);
scanf("%d", &prev_unit);
set = FALSE;
while (set == FALSE)
{
printf("Enter current unit: ");
fflush(stdin);
scanf("%d", &current_unit);
if (prev_unit > current_unit)
{
printf("ERROR: Current unit must be larger than previous unit\n");
}
else
set = TRUE;
}
consumed = current_unit - prev_unit;
}
int main()
{
/* Introduce program to users */
printf("\nThis program computes your electric bill based on these sector categories\n\n");
printf("\tResidential(R)\n");
printf("\tIndustrial(I)\n");
printf("\tCommercial(C)\n\n");
printf("Press any key to continue...");
fflush(stdin);
getchar();
#################### edit
Applying templatetypedef's solution, the program now waits for user input for the customer_name. However entering a string with a space leads to an error, and the program assumes that the word after the space is input for the next prompt.
Enter sector category: r
Enter customer name: George of the Jungle
Enter customer number: ERROR: Only numbers are allowed
Enter customer number: ERROR: Only numbers are allowed
Enter customer number:
The fflush function does not flush data out of an input stream; it is instead used to push data buffered in an output stream to the destination. This is documented here. As seen in this earlier SO question, trying to use fflush(stdin) leads to undefined behavior, so it's best to avoid it.
If you want to eat the newline from the return character entered when the user finished typing in their character, instead consider the following:
scanf("%c%*c", &sect_cat);
This will eat the newline rather than leaving it in stdin.
Hope this helps!
I think that you meant to write fflush(stdout) instead of fflush(stdin).
fflush should work with an output stream, see docs here

Resources