I have this code:
#include <stdio.h>
#include <ctype.h>
int main()
{
char x;
printf("Program shows your name and check if the first letter is capital");
while (scanf_s("%c", &x) !=1 || getchar() !='\n')
{
if (islower(x))
{
printf("Name begins with a capital letter\n");
while (getchar() != '\n')
;
}
else
{
printf("%c", x);
}
break;
}
while ((x = getchar()) != EOF)
{
printf("%c", x);
}
return 0;
}
For example:
When I type "Matthew" the result is "Mtthew". Whats wrong? I have no clue.
I tried to change almost everything in first "while" but i think the problem is not there. Any ideas?
The function getChar() removes a character from the input stream, so that it is no longer upon it. By using it within your conditional statement, it is:
Getting the character from the stream (a.k.a: removing it)
Comparing it, and finally
Discarding it (without having saved it somewhere)
If you refactor your code to consider this, then I believe your mystery character will return :-)
Change the first while to
while ((x = getchar()) != EOF && x != '\n')
EDIT: And change char x to int x because EOF isn't guaranteed to be representable by a char.
Your program worked without skipping a character when the following changes were made: (refer to comments in-line)
int x; //change to int for use with getchar()
printf("Program shows your name and check if the first letter is capital");
while (scanf("%d", &x) !=1 || getchar() !='\n')
^ //changed to d for int
But the comment made in #J.Murray's answer about getchar() eating a character is valid. So although your program worked for me, there are some input sequences for which it will not.
Note: The reason for using int as opposed to char is that getchar() can return EOF, which == -1. A char cannot contain a -1.
Certainly incorrect use of scanf_s("%c", &x)
The fscanf_s function is equivalent to fscanf except that the c, s, and [ conversion specifiers apply to a pair of arguments (unless assignment suppression is indicated by a *). The first of these arguments is the same as for fscanf. That argument is immediately followed in the argument list by the second argument, which has type rsize_t and gives the number of elements in the array pointed to by the first argument of the pair. (C111dr §K.3.5.3.2 6)
scanf_s("%c", &x, (rsize_t)1)
Other issues may exist.
Related
Playing around with code examples from K&R in Codeblocks on Windows 10 (Danish language). The following example works as expected:
#include <stdio.h>
int main() {
char c = 'a';
putchar(c);
}
However, the following prints a series of boxes with question marks, the same number as the number of characters I type:
#include <stdio.h>
int main() {
char c;
while (c = getchar() != '\n') {
putchar(c);
}
}
So it looks like an encoding issue. When run, a command prompt opens with "C:\Users\username\Desktop\filename.exe" in the header, and my username contains the Danish character "å" which is replaced by a "Õ". The command prompt uses the CP 850 character set.
(By the way, I'm not checking if the character equals EOF, since that produces odd results. Pressing enter prints the expected number of boxes, plus one for \n, but it doesn't end the program.)
You are seeing a problem of operator precedence here. As you can see on this chart, = has a lower precedence than !=.
This means that getchar() != '\n' is evaluated first.
To the compiler your code looks like this:
#include <stdio.h>
int main() {
char c;
while (c = (getchar() != '\n')) {
putchar(c);
}
}
Since 'c' is getting an incorrect value (the true/false evaluation of the expression), the output is incorrect, and the program gives the behavior you are seeing, however
#include <stdio.h>
int main() {
char c;
while ((c = getchar()) != '\n') { //<----notice brackets around c=getchar
putchar(c);
}
}
gives the output you are expecting. This illustrates the fact that you should always put brackets around such expressions to be safe.
This line is bad.
while (c = getchar() != '\n')
It should be:
while ((c = getchar()) != '\n')
There are already some correct answers within the scope of the question but there are a couple of wider problems that you need to address.
Firstly getchar() returns an int and it is important that you define the variable that takes the return value as an int so you can differentiate errors and end of file from valid chars.
Secondly, if you receive end of file or there is an error on stdin before the program encounters a \n, your code will loop forever. This is what the man page on my laptop says about getchar()
If successful, these routines return the next requested object from the stream. Character values are returned as an unsigned char converted to an int. If the stream is at end-of-file or a read error occurs, the routines return EOF.
So once getchar() returns EOF it will return EOF all the time. You need to address this in your loop condition:
#include <stdio.h>
int main()
{
int c; // c declared as int
while ((c = getchar()) != EOF && c != '\n'))
{
putchar(c);
}
if (c == EOF)
{
// handle errors and end of file as you see fit
}
}
Edit: You get the boxes because of the lack of parenthesis around the assignment, look at this question for reference as to why you should have parenthesis around an assignment used as a truth value...
Also, there is something else that is also wrong with this program, consider this example:-
For example:
What you actually wanted:-
ABCD
< newline >
What you actually typed:-
ABCD
And since the program didn't find the '\n' anywhere in the code, it leads to undefined behavior since it goes out of bounds to find it...
There are two possible solutions when your input does not contain a '\n':-
Use EOF (Suggested by many since it the best possible solution for accepting every input...)
int main() {
char c;
while ((c = getchar()) != '\n') /* Always remember to put parenthesis around
an assignment in a condition... */
putchar(c);
}
Add a newline to your input:-
int main() {
char c;
// Use fputc to modify input...
fputc('\n', stdin);
while ((c = getchar()) != '\n') /* Always remember to put parenthesis around
an assignment in a condition... */
putchar(c);
}
But, beware! This method will stop at the first iteration of newline it gets, so if you have something outside of the '\n', well it won't be printed...
I'm working through some of the exercises in K&R. Exercise 1-6 asks for verification that the expression getchar() != EOF is either 0 or 1. I understand why it is, but the code I wrote to prove it didn't work as expected. I wrote the following two snippets:
Version 1:
int main(void)
{
int c;
while (c = getchar() != EOF)
{
putchar(c);
}
printf("%d at EOF\n", c);
return 0;
}
Version 2:
int main(void)
{
int c;
while (c = getchar() != EOF)
{
printf("%d\n", c);
}
printf("%d at EOF\n", c);
return 0;
}
My questions:
When I type in a character and hit enter with version one, why do I not see either a 0 or 1 on the screen? Instead, my cursor moves to the first position on next line, which is otherwise empty. I though putchar would send c to stdout.
While the use of printf in the second version does produce a 0 or 1 appropriately, it duplicates the 1 for each non-EOF character (I see the number 1 on two consecutive lines for each character I input). Why?
Many thanks in advance for your thoughts. If there is a reference that you think would help, please send a link.
CLARIFICATION:
I know I'm assigning c a value of either 0 or 1. That's what I want to do, and it's what the exercise wants. That's also why I don't have parentheses around c = getchar(). My question deals more with understanding why the output isn't what I had expected. Sorry for any confusion.
The assignment operator = has lower precedence than the inequality operator !=.
So this:
while (c = getchar() != EOF)
Is parsed as:
while (c = (getchar() != EOF))
So then c is assigned the boolean value 1 if getchar is not EOF and 0 if it does return EOF.
As a result, the first program print the character for the ASCII code 1, which is a non-printable character. That's why you don't see anything. The second program, using the %d format specifier to printf, converts the number 1 to its string representation.
You need parenthesis to have the result of getchar assigned to c:
while ((c = getchar()) != EOF)
EDIT:
To further clarify the output you're getting, in both programs the variable c has the value 1 inside of each while loop. The difference here is that putchar is printing the character with the ASCII value of 1 (an unprintable character), while printf with %d print the textual representation of the value 1, i.e. 1.
If you changed the printf call to this:
printf("%c", c);
You would get the same output as using putchar.
As for the printing of 1 twice for each character, that is because you're actually entering two characters: the key you press, plus the enter key. When reading from the console, the getchar function doesn't return until the enter key is pressed.
What I am trying to accomplish is prompting the user with the question of do they want to run the program again. They either type y or n. If y, it reruns the program. If no, it stops the program. Anything other than those two will prompt an error and ask the question again. I'm used to C# where strings are not complicated, but in C, I guess there technically isn't strings, so we have to use either char arrays or char pointers. I've tried both, none that work that way I want, but I'm probably the problem. This is what I have.
char answer[1] = "a";
while (strcmp(answer, "y") != 0 || strcmp(answer, "n") != 0)
{
printf ("\n\nWould you like to run the program again? Type y or n. Then, hit Enter.");
scanf ("%c", answer);
if (strcmp(answer, "y") == 0)
{
main();
}
else if (strcmp(answer, "n") == 0)
{
continue;
}
else
{
printf ("\nERROR: Invalid input was provided. Your answer must be either y or n. Hit Enter to continue.");
F = getchar();
while ((getchar()) != F && EOF != '\n');
}
}
I have other while loops similar to this that work as expected, but use a float. So I'm assuming the problem is me using char here. What happens right now is that it doesn't even prompt the user for the question. It just asks the question and shows the error right afterwards. I'm sure there are other things wrong with this code, but since I can't get the prompt to work, I cannot test the rest of it yet.
I suggest using a light weight getchar() instead of the heavy scanf.
#include <stdio.h>
int c; /* Note getchar returns int because it must handle EOF as well. */
for (;;) {
printf ("Enter y or n\n");
c = getchar();
switch (c) {
case 'y': ...
break;
case 'n': ...
break:
case EOF:
exit(0);
}
}
"a" is a string literal == char id[2]={'a','\0'} //Strings are
char arrays terminated by zero, in C
'a' is a char literal
strcmp is just "compare each char in two strings, until you hit '\0'"
scanf ("%c", ___); expect an address to write to as the second
argument. Functions in C cannot modify their arguments (they don't
have access to them--they get their own local copy) unless they have
a memory address. You need to put &answer in there.
Jens has already basically answered the question, you most likely want to use getchar so that you can detect EOF easily. Unlike scanf("%c",...), getchar will not skip spaces, and I believe both versions will leave you with the unprocessed rest of the input line (a newline character ('\n') at least) after each getchar. You might want to something like
int dump;
while((dump=getchar())!='\n' && dump!=EOF) {};
So that you discard the rest of the line once you've read your first character of it.
Otherwise, the next getchar will get the next unprocessed character of the same line. ('\n' if the line was a single letter).
Here is one way to do it. It is by no means the only way to do it, but I think it accomplishes what you want. You should not call the main function recursively.
#include <stdio.h>
#include <stdlib.h>
void run_program()
{
printf("program was run.");
}
int main() {
char answer[2] = "y\0";
int dump;
do {
if (answer[0] == 'y')
{
run_program(); /* Not main, don't call main recursively. */
}
printf ("\n\nWould you like to run the program again? Type y or n. Then, hit Enter.\n");
scanf ("%1s", answer);
/* Dump all other characters on the input buffer to
prevent continuous reading old characters if a user
types more than one, as suggested by ThorX89. */
while((dump=getchar())!='\n' && dump!=EOF);
if (answer[0] != 'n' && answer[0] != 'y')
{
printf ("Please enter either y or n\n");
}
} while (answer[0] != 'n');
return 0;
}
Using %s instead of %c, reads in the new line so that the new line character is not in the stdin buffer which would become answer then next time scanf was called.
The run_program function is just a function where you would put your program's logic. You can call it whatever you want. I did this to separate out the menu logic from the logic of the actual program.
Well, you are comparing two strings instead of characters.
If you want to compare two character you have to follow this syntax:
char c;
scanf("%c",&c);
if(c == 'y')
//do something
else
//do nothing
I have to write a program in C for class that reads in one character at a time and we have to use scanf. I got it to work with input from only the keyboard however, my teacher will be testing the code with file redirection as well.
int end; //return value of scanf
int length1; //length of string exp1
char temp, //temp char for input
char exp1[81]; //string
printf ("Please enter in a regular expression:\n");
end = scanf ("%c", &temp);
while (temp != '\n' || end == 1) { //check if end of input
length1 = check(temp, length1, exp1); //returns length of exp1
end = scanf ("%c", &temp); //scan next char for loop
}
I've been at this one tiny problem for hours trying to figure it out so any pointers are helpful. Thanks!
EDIT: I've tried using the kbhit() function in an if statement to check if they typed in the input or if the input is from a file. However, I don't have conio.h, is there any alternative while still using scanf?
Your narrower-scope question has already been answered, but let me give you a piece of good advice. If you are not forced to use scanf() in class (i. e. you are writing real, production code), then
Just get rid of scanf(). It's evil. It does not do what you think it does.
If you want to get one character at a time, then use the function that gets one character at a time. And that is fgetc(stdin).
int c;
while ((c = fgetc(stdin)) != EOF) {
/* process `c' */
}
scanf returns EOF if an input failure occurs before the first conversion (if any) has completed. So you may check on that. But you only read one character each time, that doesn't seem necessary since you already check if the return value if 1.
I think the error is in the logic in your while condition, it should be:
while (temp != '\n' && end == 1)
// ^^
You need to compare scanf output with EOF
while(scanf("%c", &temp) != EOF)
{
}
You could convert this to something like:
do{
length1 = check(temp, length1, exp1); //returns length of exp1
end = scanf ("%c", &temp); //scan next char for loop
}while (temp != '\n' && end != EOF) ;
#include <stdio.h>
void main()
{
char ans='n';
do
{
printf("\n Enter yes or no:");
scanf("%c",ans);
printf("\n entered %c",ans);
}while(ans == 'y');
}
As do while the loop is getting exccuted and that scanf is working and prnting my answer (say my answer is y) , its coming for 2nd time but not doing the scan and getting exited . May i know the reason for this ? why it is happening and what is the correct way to handle the infinite loop.
First up, you're missing a & in the scanf:
scanf("%c", &ans);
^
Second, you're not handling the newline, and the %c format specifier doesn't ignore blanks. So you read a character, press return, and the next scanf is immediately satisfied by that \n. To ignore blanks in scanf try:
scanf(" %c", &ans);
^
Not only are you missing the &address-of operator as indicated in other answers, but you're also missing the return value checks. Consider if a user presses CTRL+Z in Windows, or CTRL+d in Linux, to close stdin. Your loop would run infinitely and freeze your app ;)
if (scanf("%c", &ans) != 1) {
break;
}
Alternatively, I would suggest using getchar because it's far cleaner:
int main(void) { /* NOTE: There is no "void main()" entrance point in C. main should always return 'int'. */
int c;
do {
c = getchar();
} while (c == 'y');
return 0;
}
Use fflush(stdin) to flush those return feeds.
But when you are inputting a single character, then why not use getchar()?
EDIT:
As correctly pointed out by cnicutar here, fflush(stdin) has undefined behaviour. There doesn't seem to be any inbuilt function to take care of that and hence must be taken care of in the code itself.
One example could be:
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
Thanks for pointing that out there!