This question already has answers here:
Why does printf not flush after the call unless a newline is in the format string?
(10 answers)
Closed 5 years ago.
I couldn't understand why the following behavior happens in my code
First lets check if there exists number that dividable by 5
int count = 1;
while (count < 10) {
if (count%5 == 0) {
fprintf(stderr, FIND);
exit(1);
} else {
printf("Not Yet");
count += 1;
}
Normally, I'm expecting that it will print "not yet" four times before it print FIND
however, it actually print FIND immediately even first four number doesn't go to the if statement. There is no output of "Not Yet". The output is simply
FIND
Anyway, I try to debug by adding one more line within the if statement.
int count = 1;
while (count < 10) {
if (count%5 == 0) {
printf("%d\n", count);
fprintf(stderr, INVALID_LINE);
exit(1);
} else {
printf("Not Yet");
count += 1;
}
}
The output becomes
Not YetNot YetNot YetNot Yet5
FIND
I couldn't understand
First code, why the program execute if-statement even if the condition doesn't satisfied.
Second code, when one print line is added, the code actually behave what I've expected
stderr is unbuffered. Anything you write to it goes out immediately. stdout, which printf writes to, is line buffered-- it only goes out when a new line character is encountered.
Related
I'm writing a C program which reads a text file line by line with a certain format to it.
I made a do { ... } while(!feof(file)); loop but it always loops one too many times. This is an issue because I have made it so that when my program expects to read something but gets nothing, it throws an error, so now it is throwing an error every time because it reaches the end of the file at the top of my loop.
I figured this is because the eof flag is triggered only once you try to fscanf something but there is nothing there. How can I fix this problem? Putting a final fscanf at the bottom doesn't work because if it's not at the end of the file, it will mess all the readings up and shift everything by one.
do {
read = fscanf(/*...*/);
if (read != 1)
{
return -1;
}
// Read grades
read = fscanf(/*...*/);
if (read != 3)
{
return -1;
}
// Read student kind
int student_kind = 0;
read = fscanf(/*...*/);
if (read != 1)
{
return -1;
}
if (student_kind < 0 | student_kind > 2)
{
printf("Invalid student kind");
return -1;
}
SCIPER sciper_teammate = 0;
read = fscanf(/*...*/);
if (read != 1)
{
return -1;
}
} while (!feof(file));
Since you are using fscanf():
ISO/IEC 9899:2017
§ 7.21.6.2 - 16 - The fscanf function returns the value of the macro EOF if an input failure occurs before the first conversion (if any) has completed. Otherwise, the function returns the number of input items assigned, which can be fewer than provided for, or even zero, in the event of an early matching failure.
EOF is a macro with the value of -1, by itself it's not distinguishable as for the reasons why it occurs.
For this distinction § 7.21.6.2 - 19 recommends the use of feof() for end-of-file and ferror() for I/O error:
EXAMPLE 3 To accept repeatedly from stdin a quantity, a unit of measure, and an item name:
#include<stdio.h>
/*...*/
int count; floatquant;
charunits[21], item[21];
do {
count = fscanf(stdin, "%f%20sof%20s", &quant, units, item);
fscanf(stdin,"%*[^\n]"); //here discarding unread characters in the buffer
} while(!feof(stdin) && !ferror(stdin));
This should work in your case but personaly. I don't like this approach since if you input less values than what fscanf is expecting this will fail, normaly resulting in an infinite loop.
My approach when reading formated input, is to check the inputed values.
For a sample input of 2 integers you can do something like:
Live sample
#include <stdio.h>
int main()
{
int a, b;
FILE* file;
if(!(file = fopen("file.txt", "r"))){
return 1;
}
while(fscanf(file, "%d %d", &a, &b) == 2){ //read each 2 integers in the file, stop when condition fails, i.e. there are nothing else to read or the read input is not an integer
printf("%d %d\n", a, b);
}
}
This addresses all input failures and will end the cycle for I/O error, for EOF and for bad inputs.
The code is taken from an exam question which I did not know the answer for:
int c = 0;
while (c < 5)
{
if (c == 2)
{
continue;
}
printf ("data %d", ++c);
}
I know that it prints nothing, but I would like to know why?
Any help would be appreciated.
By default, on POSIX systems, stdout is a buffered stream which will only flush when it hits a line feed or when it's explicitly asked to flush using fflush(stdout);
Add fflush(stdout); after the printf() call and then your program should output:
data 1data 2
After that, your program will be stuck in an infinite loop, because the condition in your while statement will always be evaluated to true.
There are some buffering issues. If you add fflush(stdout) after the printf, you get data 1data 2. It doesn't go further than data2 because once c is equal to 2, it will keep hitting the if case and skipping the increment. Try the following and you will get data 1data 2:
int c = 0;
while (c < 5)
{
if (c == 2)
{
continue;
}
printf ("data %d", ++c);
fflush(stdout);
}
Once c == 2 is true, then you will stay in the loop and keep hitting the if statement. So you'll never increment once c is set to 2.
int c = 2;
if(c == 2) {
continue;
}
printf("%d", c); // this will never get hit once c is 2 since continue will
//make the program jump to the next iteration of the loop.
//Also by not flushing after the print, you aren't clearing the buffer and are then not accepting the next print.
You don't need to fflush(stdout) if the infinite loop is fixed though.
This question already has answers here:
C/C++ printf() before scanf() issue
(2 answers)
Closed 4 years ago.
I am a java programmer and started learning C recently. I was going through headfirst C and wrote one of the example programs in Eclipse (with CDT). Here is the program
#include <stdlib.h>
#include <stdio.h>
int main()
{
char card_name[3];
puts("Enter the card_name: ");
scanf("%2s",card_name);
int val = 0;
if(card_name[0] == 'K'){
val = 10;
}else if (card_name[0] == 'Q'){
val = 10;
}else if(card_name[0] == 'J'){
val = 10;
}else if(card_name[0] == 'A'){
val = 11;
}else{
val = atoi(card_name);
}
printf("The card value is: %i\n",val);
return 0;
}
When I run it on eclipse, the line containing puts should be executed and then the user should enter in eclipse console and then the scanf line should execute.
But it doesn't happen that way, when I run it, it just expects the user to enter first on the eclipse console, then execute the puts line and finally the scanf line. I couldn't understand this behavior. Can someone help me on this ?
Depending on how the buffering of the output is configured, you might nee to be very explicit about when to actually make the output.
Usually a newline at the end of text is sufficient, i.e. there must be something special in your environment, I suspect the Eclipse console, but that is just guessing.
Especially when attempting to do prompt and reading within one line, it is wise to use a
/* ... */
puts("Enter the card_name: ");
fflush(stdout);
/* ... */
at exactly the point where you need the output you have already send.
In your case the buffering causes this sequence:
put the prompt in output buffer
environment is configured not to automatically output immediatly
(this is where I propose to flush in order to get output)
scanf is executed
user input
your program does not do anythign visible, though executing completly
put the final message into output
ending the program causes final output of anything buffered
I.e. the scanf is not executed before the first puts, it is only the visible effect which gets delayed.
Im using fgets to read from 2 different pipes which have been sent 2 different messages thus should be returning 2 different messages. I have 2 pipes for each and closed the unneeded child end, all my fprintfs are flushed yet theyre both returning the same message then it just hangs. I have no idea why. Debugging didnt help me though i could have missed something.
int reader(FILE *output, int **pipes, char *getMessage) {
if(output == NULL) {
fprintf(stderr, "Player quit\n");
}
fgets(getMessage, sizeof(getMessage), output);
printf("mes %s\n", getMessage);
return 0;
}
Is my reader method (I am using the same buffer for both but i was using memset to try to clear it each time:
printf("test%c\n", roundDeck[deckPos]);
fprintf(input[pickturn], "yourturn %c\n", roundDeck[deckPos]);
fprintf(stdout, "yourturn %c\n", roundDeck[deckPos]);
fflush(input[pickturn]);
allHeldCards[pickturn][1] = roundDeck[deckPos];
roundDeck[deckPos] = '-';
//fclose(inPut);
deckPos++;
if(deckPos == 16) {
deckPos = 0;
}
printf("pt %d\n", pickturn);
reader(output[pickturn], pipes, getMessage);
if(msgProcess(pickturn, allIds, allFlags, allHeldCards,
getMessage, pipes, roundDeck,
deckPos, numPlayers, input) == 1) {
roundDeck[deckPos] = '-';
deckPos++;
if(deckPos == 16) {
deckPos = 0;
}
}
memset(getMessage, 0, 50);
the inputs were changing where they needed to do on the outside so maybe Im using memset incorrectly?
There is a problem here:
fgets(getMessage, sizeof(getMessage), output);
Since getMessage has type char *, then sizeof(getMessage) is sizeof(char *) which is likely to be 4 or 8. You read that many bytes from the "output" into getMessage.
Instead, you need to specify how many bytes to read. Even if you replace sizeof(getMessage) with your buffer size, that means it will block until all that number of bytes have been read, or the input is closed. Either your message protocol has to contain the length it expects to read, or you have to define your function to read until the input is closed or a certain delimiter occurs.
Then you have to make sure that the data you read contains a null-terminated string before you try and print it with %s or any other function that expects a string.
Not clear why your inputs are called output and your outputs are called input either.
It's hard to debug further without seeing more of a complete program than just these snippets
I am working on a program that determines the mode of a set of values for example (3 4 2 3 3) should print out "3". The catch is the program must receive the option of the mathematical function to execute and its arguments as parameters in the main function so no user input. Everything must be inserted in the command line and check by using pointers. My program works except for example say the user enters (mode) but doesn't enter in any values after. This should then print a message that just says "ERROR" and the program ends. However it does not instead it prints
Johns-MacBook-Pro-2:AdvanceCalc jvdamore$ ./a.out mode
Segmentation fault: 11
when it should print
Johns-MacBook-Pro-2:AdvanceCalc jvdamore$ ./a.out mode ERROR
below is my code. So my question is does my if statement with strcmp(p[2], "") == 0 work in order to produce the desired error message? or am I doing something wrong?
int main(int n, char **p)
{
int i, x, A[100];
if (strcmp(p[1], "mode")==0){
if (strcmp(p[2], "") == 0){
printf("ERROR");
return -1;
}
for(i=2;i<n;i++){
if (sscanf(p[i], "%d", &x) != 1) {
printf("ERROR");
return -1;
}
if (x<1 || x>30){
printf("ERROR");
return-2;
}
A[i-2]= x;
}
find_mode(A, n-2);
}
Rather than comparing a string to "" with strcmp, you need to see if it is NULL. strcmp( NULL, "" ) does not work very well, and you should instead do:
if( p[2] == NULL )
(well, really, you should rename the varaible argv, and there are several other issues, but this is the main problem. Make sure you have checked that p[1] is not NULL before you reference p[2])