I'm new to programming and have been working on an assignment in class. For some strange reason the program keeps printing 2 different printf's on the same line and not giving me a chance to input information
Here is the code:
#include <stdio.h>
#include <stdlib.h>
int main (void)
{ char Name[20];
char cid1[6]="", cid2[6]="", cid3[6]="", cid4[6]="", cid5[6]="", cid6[6]="";
char Description1[21]="", Description2[21]="", Description3[21]="", Description4[21]="", Description5[21]="", Description6[21]="";
int hrs1 = 0, hrs2=0, hrs3=0, hrs4=0, hrs5=0, hrs6=0;
char grade1[2]="",grade2[2]="",grade3[2]="",grade4[2]="",grade5[2]="",grade6[2]="";
printf("Enter Students Name ");
fgets(Name, 20, stdin);
printf("Enter Class ID ");
scanf("%5s", cid1);
printf("Enter Class Description "); // Problem
fgets(Description1, 20, stdin); // here
printf("Enter Class Hours ");
scanf("%d", &hrs1);
printf("Enter Class Grade ");
fgets(grade1, 1, stdin);
printf("%s\n", Name);
printf("%s\n", cid1);
printf("%s\n", Description1);
printf("%d\n", hrs1);
printf("%s\n", grade1);
system("pause");
return 0;
The area marked “Problem here” is where the problem is currently occurring. In stead of prompting for the class description it will skip straight to entering class hours and completely ignore the enter class grade at the bottom.
It prints it as: Enter Class DescriptionEnter Class Hours.
They are trying to teach you the difference between scanf and fgets. And they are probably tricking you by telling you that the Class ID has to be 4 characters.
So if your Class ID is "1234" and you hit Enter after, what ends up in stdin is:
1234\r\n
The %5s format in scanf says to read 5 characters and then move on. So, you read in 1234\r and leave \n in the stdin stream. Then when fgets executes, it reads in the \n and moves on.
From the above on fgets:
Get string from stream
Reads characters from stream and stores them as a C string into str
until (num-1) characters have been read or either a newline or the
end-of-file is reached, whichever happens first.
There is a newline left in the input buffer, from the previous input operation. One way to get rid of it is to read character by character until you've read a '\n'.
You did not consume the newline characters by your scanf calls. As fgets returns when it reads a newline character, it returns immediatelly.
You could change the scanf format string to consume newline characters as follow
scanf("%5s\r\n", cid1);
It seems like you are running this on windows. Windows has issues with flushing its stdin properly. Try using an
fflush(stdin);
after any reads from the console.
Related
I am trying to create a program that repeatedly asks the user for input. However, in this case, the program just keeps printing "Enter your input" until it crashes after I enter something for the first time.
#include <stdio.h>
int main() {
while (1) {
char input[100];
printf("Enter a input: ");
scanf("%[^\n]s", input);
}
}
In:
scanf("%[^\n]s", input);
There are 2 problems:
The s is not part of that specific specifier, it should be only %[^\n].
That specifier leaves the \n newline character in the input buffer.
Your cycle will enter an infinite loop because there is always something to read there, but it's something that must not be parsed and should remain in the buffer.
A simple way to get rid of it is to place a space before the specifier:
scanf(" %[^\n]", input);
^
|
You are asking scanf() to read everything up to, but not including, the line break that ends the user's input.
So, the line break stays in the input buffer. Then on subsequent calls to scanf(), the line break is still not read from the input buffer, preventing scanf() from reading any new input.
You need to read that line break from the input buffer so that a subsequent call to scanf() can read the user's next input.
This was supposed to be very simple, but I'm having trouble to read successive inputs from the keyboard.
Here's the code:
#include <string.h>
#include <stdio.h>
int main()
{
char string[200];
char character;
printf ("write something: ");
scanf ("%s", string);
printf ("%s", string);
printf ("\nwrite a character: ");
scanf ("%c", &character);
printf ("\nCharacter %c Correspondent number: %d\n", character, character);
return 0;
}
What is happening
When I enter a string (e.g.: computer), the program reads the newline ('\n') and puts it in character. Here is how the display looks like:
write something: computer
computer
Character:
Correspondent number: 10
Moreover, the program does not work for strings with more than one word.
How could I overcome these problems?
First scanf read the entered string and left behind \n in the input buffer. Next call to scanf read that \n and store it to character.
Try this
scanf (" %c", &characte);
// ^A space before %c in scanf can skip any number of white space characters.
Program will not work for strings more than one character because scanf stops reading once find a white space character. You can use fgets instead
fgets(string, 200, stdin);
OP's first problem is typically solved by prepending a space to the format. This will consume white-space including the previous line's '\n'.
// scanf("%c", &character);
scanf(" %c", &character);
Moreover, the program does not work for strings with more than one word. How could I overcome these problems?
For the the 2nd issue, let us go for a more precise understanding of "string" and what "%s" does.
A string is a contiguous sequence of characters terminated by and including the first null character. 7.1.1 1
OP is not entering a string even though "I enter a string (e.g.: computer)," is reported. OP is entering a line of text. 8 characters "computer" followed by Enter. There is no "null character" here. Instead 9 char "computer\n".
"%s" in scanf("%s", string); does 3 things:
1) Scan, but not save any leading white-space.
2) Scan and save into string any number of non-white-space.
3) Stop scanning when white-space or EOF reached. That char is but back into stdin. A '\0' is appended to string making that char array a C string.
To read a line including spaces, do not use scanf("%s",.... Consider fgets().
fgets(string, sizeof string, stdin);
// remove potential trailing \r\n as needed
string[strcspn(string, "\n")] = 0;
Mixing scanf() and fgets() is a problem as calls like scanf("%s", string); fgets(...) leave the '\n' in stdin for fgets() to read as a line consisting of only "\n". Recommend instead to read all user input using fgets() (or getline() on *nix system). Then parse the line read.
fgets(string, sizeof string, stdin);
scanf(string, "%c", &character);
If code must user scanf() to read user input including spaces:
scanf("%*[\n]"); // read any number of \n and not save.
// Read up to 199 `char`, none of which are \n
if (scanf("%199[^\n]", string) != 1) Handle_EOF();
Lastly, code should employ error checking and input width limitations. Test the return values of all input functions.
What you're seeing is the correct behavior of the functions you call:
scanf will read one word from the input, and leave the input pointer immediately after the word it reads. If you type computer<RETURN>, the next character to be read is the newline.
To read a whole line, including the final newline, use fgets. Read the documentation carefully: fgets returns a string that includes the final newline it read. (gets, which shouldn't be used anyway for a number of reasons, reads and discards the final newline.)
I should add that while scanf has its uses, using it interactively leads to very confusing behavior, as I think you discovered. Even in cases where you want to read word by word, use another method if the intended use is interactive.
You can make use of %*c:
#include <string.h>
#include <stdio.h>
int main()
{
char string[200];
char character;
printf ("write something: ");
scanf ("%s%*c", string);
printf ("%s", string);
printf ("\nwrite a character: ");
scanf ("%c%*c", &character);
printf ("\nCharacter %c Correspondent number: %d\n", character, character);
return 0;
}
%*c will accept and ignore the newline or any white-spaces
You cal also put getchar() after the scanf line. It will do the job :)
The streams need to be flushed. When performing successive inputs, the standard input stream, stdin, buffers every key press on the keyboard. So, when you typed "computer" and pressed the enter key, the input stream absorbed the linefeed too, even though only the string "computer" was assigned to string. Hence when you scanned for a character later, the already loaded new line character was the one scanned and assigned to character.
Also the stdout streams need to be flushed. Consider this:
...
printf("foo");
while(1)
{}
...
If one tries to execute something like this then nothing is displayed on the console. The system buffered the stdout stream, the standard output stream, unaware of the fact it would be encounter an infinite loop next and once that happens, it never gets a chance to unload the stream to the console.
Apparently, in a similar manner whenever scanf blocks the program and waits on stdin, the standard input stream, it affects the other streams that are buffering. Anyway, whatsoever may be the case it's best to flush the streams properly if things start jumbling up.
The following modifications to your code seem to produce the desired output
#include <string.h>
#include <stdio.h>
int main()
{
char string[200];
char character;
printf ("write something: ");
fflush(stdout);
scanf ("%s", string);
fflush(stdin);
printf ("%s", string);
printf ("\nwrite a character: ");
fflush(stdout);
scanf ("%c", &character);
printf ("\nCharacter %c Correspondent number: %d\n", character, character);
return 0;
}
Output:
write something: computer
computer
write a character: a
Character a Correspondent number: 97
printf("Type first name:"); scanf("%[^\n]%*c",msg);
printf("Type last name: "); scanf("%[^\n]%*c",aux2);
....
printf("Type adress:"); scanf("%[^\n]%*c",aux2);
....
printf("Type phone:"); scanf("%[^\n]%*c",aux2);
I want to read some string with spaces.
But scanf here has no effect..
After running this,I get:"Type first name:Type last name:Type adress:Type phone:")
Also ,I use in my code scanf("%c",&c)` to read some chars...
What's the problem here,why I can't read those string?
*edited
It's still not obvious what your problem is (to me, anyway), but if you want to read a line of text including spaces, fgets is probably the easiest solution.
char buf[100];
fgets(buf, sizeof(buf), stdin);
Note that fgets will stop reading once it encounters the \n character but it will append it to your buffer.
It seems that a \n character (which probably came from previous inputs) is in the input stream(stdin) when execution of the program reaches the scanfs which you posted.
scanf("%[^\n]%*c",aux2);
will not scan \n if it is the next character in the stdin and fails.To fix it,just add a
getchar();
just before the first scanf. This will gobble up the trailing \n from the stdin.
Currently im trying to learn simple C Programs. But, i came into this situation :
#include<conio.h>
#include<stdio.h>
void main()
{
char c;
int tryagain=1;
while(tryagain>0){
printf("Enter the Character : ");
scanf("%c",&c);
printf("You entered the character \"%c\" and the ascii value is %d",c,c);
getch();
clrscr();
tryagain=0;
printf("You want to Trry again Press 1 : ");
scanf("%d",&tryagain);
clrscr();
}
}
The program is fine when user first enter a character. And, when it ask to continue. And, user enter 1 then it is behaving weired. It automatically input blank character and prints the ascii and goto the same place.
How can i resolve this? And, specially, Why is the reason for this?
And, Im sorry about my poor english!
Thank you in Advance.
When you use
scanf("%d",&tryagain);
the number is read into tryagain but the newline character, '\n', is still left on the input stream. The next time you use:
scanf("%c",&c);
the newline character is read into the c.
By using
scanf("%d%*c",&tryagain);
the newline is read from the input stream but it is not stored anywhere. It is simply discarded.
The issue is that you are reading a single number in the second scanf, but user inputs more than a single number there, the user also input a new line character by pressing .
User enters "1\n". Your scanf reads "1", leaving out "\n" in the input stream. Then the next scanf that reads a character reads "\n" from the stream.
Here is the corrected code. I use getc to discard the extra new line character that is there.
#include <stdio.h>
void main()
{
char c;
int tryagain = 1;
while (tryagain > 0) {
printf("Enter a character: ");
scanf("%c", &c);
printf("You entered the character \"%c\" and the ascii value is %d\n", c, c);
tryagain = 0;
printf("If you want to try again, enter 1: ");
scanf("%d", &tryagain);
// get rid of the extra new line character
getc(stdin);
}
}
Also, as a side note, you use conio.h which is not part of standard C, it's MS-DOS header file, thus it's not portable C you are writing. I have removed it from my code, but you might wish to keep it.
In my program I'm just calculating the costs of things. However, at the end I want a little break at the program asking for the user to just press the Enter button. I supposed getchar() would work here but it doesn't even stop, it just continues to keep printing. I even tried to put a space after the scant formats like scanf("%s ").
So two things how do I stop the program to ask for input at getchar() and how do I make it recognize just a enter button.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char hotels_houses[5];
int houses, hotels, cost;
printf("Enter amount of houses on board: \n");
scanf("%s", hotels_houses);
houses = atoi(hotels_houses);
printf("Enter amount of hotels on board: \n");
scanf("%s", hotels_houses);
hotels = atoi(hotels_houses);
printf("Cost of houses: %d\n", houses);
printf("Cost of hotels: %d\n", hotels);
cost = (houses *40) + (hotels * 115);
puts("Click enter to calculate total cash ");
getchar(); /* just a filler */
printf("Total cost: %d\n", cost);
return(0);
}
My best guess is that it is retrieving the remaining newline after the user has entered their input. You can print out the return value to verify. If I'm correct, it'll be "10" or "13" depending on your OS.
You might want to change your program to use getline. There are other examples on how to write a get line at How to read a line from the console in C?
When code calls scanf("%s", ... the program waits for input.
You type "123" and nothing happens yet as stdin is buffered input and waits for a \n thus the system has not given any data to scanf().
Then you type "\n" and "123\n" is given to stdin.
scanf("%s",...) reads stdin and scans optional leading white-space then the non-white space "123". Finally it sees "\n" and puts it back in stdin and completes.
Code calls scanf("%s", ... again. scanf() scans the "\n" as part of its scanning optional leading white-space. Then it waits for more input.
You type "456" and nothing happens yet as stdin is buffered input and waits for a \n thus the system has not given any data to scanf().
Then you type "\n" and "456\n" is given to stdin.
scanf("%s",...) reads stdin and scans optional leading white-space then the non-white space "456". Finally it sees "\n" and puts it back in stdin and completes.
Finally you call getchar() and puff, it reads the previous line's \n from stdin.
So how to do I stop the program to ask for input at getchar() and how do I make it recognize just a enter button.
Best approach: use fgets()
char hotels_houses[5+1];
// scanf("%s", hotels_houses);
fgets(hotels_houses, sizeof hotels_houses, stdin);
houses = atoi(hotels_houses);
...
// scanf("%s", hotels_houses);
fgets(hotels_houses, sizeof hotels_houses, stdin);
hotels = atoi(hotels_houses);
...
puts("Click enter to calculate total cash ");
fgets(bhotels_houses, sizeof hotels_houses, stdin); // do nothing w/hotels_houses
printf("Total cost: %d\n", cost);
Checking for a NULL return value from fgets() is useful to test for a closed stdin.
Using strtol() has error checking advantages over atoi().