This question already has answers here:
Why doesn't getchar() wait for me to press enter after scanf()?
(10 answers)
Closed 3 years ago.
I'm learning programmation in C and tried to create a program that asks the user his age. When the user writes his age (for example 18) he gets the message "So you're 18 years old". When I execute the .exe file it automatically closes after you see the message, so fast that you don't see it. Then I added getchar so that the user reads the message and then presses Enter to quite. Here's the program I wrote:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int age=0;
printf("How old are you?\n");
scanf("%d",&age);
printf("So you're %d years old", age);
getchar();
return 0;
}
Unfortunately, when I execute the .exe file, it still closes automatically like if the getchar() doesn't exist and I don't know why.
scanf("%d",&age);
When the execution of the program reaches the above line,you type an integer and press enter.
The integer is taken up by scanf and the \n( newline character or Enter )which you have pressed remains in the stdin which is taken up by the getchar().To get rid of it,replace your scanf with
scanf("%d%*c",&age);
The %*c tells scanf to scan a character and then discard it.In your case,%*c reads the newline character and discards it.
Another way would be to flush the stdin by using the following after the scanf in your code:
while ( (c = getchar()) != '\n' && c != EOF );
Note that c is an int in the above line
You're only having trouble seeing the result because you're starting the program from a windowing environment, and the window closes as soon as its internal tasks are completed. If you run the compiled program from a command line in a pre-existing shell window (Linux, Mac, or Windows), the results will stay on the screen after you're returned to the prompt (unless you've ended by executing a clear-screen of some sort). Even better, in that case, you don't need the extraneous getchar() call.
For Windows, after opening the command prompt window, you'd issue a "cd" command to change to the directory that contains the compiled program, and then type its name. For Linux (and, I presume, Mac, since Mac is UNIX under the hood), you'd need to type ./ ahead of the program name after changing to the appropriate directory with "cd".
Related
Following "The C Programming Language" by Kernighan and Ritchie, I am trying to enter the program described on page 18 (see below).
The only changes I made were to add "int" before "main" and "return 0;" before closing the brackets.
When I run the program in Terminal (Mac OS 10.15) I am prompted to enter an input. After I enter the input I am prompted to enter an input again - the "printf" line is apparently never reached and so the number of characters is never displayed.
Can anyone help me with the reason why EOF is never reached letting the while loop exit? I read some other answers suggesting CTRL + D or CTRL + Z, but I thought this shouldn't require extra input. (I was able to get the loop to exit with CTRL + D).
I have also pasted my code and the terminal window below.
#include <stdio.h>
int main(){
long nc;
nc = 0;
while( getchar() != EOF )
++nc;
printf("%ld\n", nc);
return 0;
}
From pg. 18 of "The C Programming Language
My screenshot
You already have the correct answer: when entering data at the terminal, Ctrl-D is the proper way to indicate "I'm done" to the terminal driver so that it sends an EOF condition to your program (Ctrl-Z on Windows). Ctrl-C breaks out of your program early.
If you ran this program with a redirect from an actual file, it would properly count the characters in the file.
EOF means end of file; newlines are not ends of files. You need to press CTRL+D to give the terminal an EOF signal, that's why you're never exiting your while loop.
If you were to give a file as input instead of through the command line, then you would not need to press CTRL+D
Adding to the two good answers I would stress that EOF does not naturally occur in stdin like in other files, a signal from the user must be sent, as you already stated in your question.
Think about it for a second, your input is a number of characters and in the end you press Enter, so the last character present in stdin is a newline character not EOF. For it to work EOF would have to be inputed, and that is precisely what Ctrl+D for Linux/Mac or Ctrl+Z for Windows, do.
As #DavidC.Rankin correctly pointed out EOF can also occur on stdin through bash piping e.g. echo "count this" | ./count or redirecting e.g. ./count < somefile, where somefile would be a text file with the contents you want to pass to stdin.
By the way Ctrl+C just ends the program, whereas Ctrl+D ends the loop and continues the program execution.
For a single line input from the command line you can use something like:
int c = 0;
while((c = getchar()) != EOF && c != '\n'){
++nc;
}
This question already has answers here:
Why doesn't getchar() wait for me to press enter after scanf()?
(10 answers)
Closed 3 years ago.
I'm learning programmation in C and tried to create a program that asks the user his age. When the user writes his age (for example 18) he gets the message "So you're 18 years old". When I execute the .exe file it automatically closes after you see the message, so fast that you don't see it. Then I added getchar so that the user reads the message and then presses Enter to quite. Here's the program I wrote:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int age=0;
printf("How old are you?\n");
scanf("%d",&age);
printf("So you're %d years old", age);
getchar();
return 0;
}
Unfortunately, when I execute the .exe file, it still closes automatically like if the getchar() doesn't exist and I don't know why.
scanf("%d",&age);
When the execution of the program reaches the above line,you type an integer and press enter.
The integer is taken up by scanf and the \n( newline character or Enter )which you have pressed remains in the stdin which is taken up by the getchar().To get rid of it,replace your scanf with
scanf("%d%*c",&age);
The %*c tells scanf to scan a character and then discard it.In your case,%*c reads the newline character and discards it.
Another way would be to flush the stdin by using the following after the scanf in your code:
while ( (c = getchar()) != '\n' && c != EOF );
Note that c is an int in the above line
You're only having trouble seeing the result because you're starting the program from a windowing environment, and the window closes as soon as its internal tasks are completed. If you run the compiled program from a command line in a pre-existing shell window (Linux, Mac, or Windows), the results will stay on the screen after you're returned to the prompt (unless you've ended by executing a clear-screen of some sort). Even better, in that case, you don't need the extraneous getchar() call.
For Windows, after opening the command prompt window, you'd issue a "cd" command to change to the directory that contains the compiled program, and then type its name. For Linux (and, I presume, Mac, since Mac is UNIX under the hood), you'd need to type ./ ahead of the program name after changing to the appropriate directory with "cd".
This question already has answers here:
Simple program adding "D" to output
(3 answers)
Why does C program print 0D instead of 0? (When EOF sent as Ctrl+D) [duplicate]
(1 answer)
Closed 5 years ago.
I was coding a very simple programme to detect word pattern by entering to stdin and return the times found the pattern.
However the code return me the correct number but follow a char D.
#include <stdio.h>
#include "string.h"
#define MAXLINE 1000 /* maximum input line length */
char pattern[] = "ould"; /* pattern to search for */
/* print all lines from standard input that match pattern */
int main()
{
char line[MAXLINE];
int found = 0;
while (fgets(line, MAXLINE, stdin) != NULL)
if (strstr(line, pattern) != NULL) {
printf("%s", line);
found++;
}
printf("%d \n", found);
return 0;
}
Result:
glaroam2-180-76:Lab2 apple$ ./find0
fould
fould
1D
The code is correct (apart from the #include "string.h" which should be
#include <string.h>)1, the problem is that when you press
Ctrl+D on your terminal, your terminal might write
something on the terminal, which you cannot control and this output might be
^D
After fgets returns NULL, you do printf("%d \n", found); which prints the '1'.
But because there was ^D on the terminal, the ^ was replaced by the '1' and
you end up with:
1D
Change your last printf to this:
printf("\n\n%d \n, found);
And you might see only a '1' in the next lines of the output.
This has nothing to do with your C program, it's the behaviour of your terminal.
My terminal for example doesn't print when pressing Ctrl+D,
but when pressing Ctrl+C I get ^C. There's nothing you
can do.
edit
With There's nothing you can do I mean that you cannot control the way the
terminal from you C program without calling external tools like stty. While
this might solve your problem, you are loosing portability.
However, before you start you program, you can configure your terminal using a
program like stty. See Jonathan Leffler's answer for more info on that.
Fotenotes
1As Jonathan Leffler points out in the comments, using quotes instead
of angle brackets for system headers is not an error per se. For example my GCC
compiler searches in the same directory of the compiled file for headers that
were included with quotes. But in general, it's a good practice to include the
header files included provided by your system with angle brackets.
It's a terminal setting: echoctl. It means that when you type Control-D, the terminal echoes ^D, and then the 1 overwrites the ^. Try using:
stty -echoctl
and then rerunning your program.
With that said, I'm surprised that the D isn't wiped out by the blank after the %d in the format string. I suspect your actual code may be missing that. When I tested on my Mac, the program with the space after the %d did not show the D for long enough for me to spot it; when I removed that space, I got the output shown in the question.
This question already has answers here:
Why does program not execute final printf statement?
(2 answers)
Closed 6 years ago.
I've been trying to learn some C language via "The C Programming Language by BRIAN W KERNIGHAN & DENNIS M. RITCHIE", and I've got a question that I cannot understand.
Here's the deal, in section 1.5 (page 17) related to character counting of an input, here's my code:
#include <stdio.h>
int main()
{
double nc;
for (nc = 0; getchar() != EOF; ++nc);
printf("%0.f\n", nc);
}
This part:
printf("%0.f\n", nc);
Should print the actual character counter, right? The problem is that it gives me exactly nothing. I've been trying it via Code Blocks and also via terminal by doing "cc code.c", and all it does it just waits for me to put and input, and just nothing more.
Am I missing something here?
Thanks in advance,
Anoubis
You are trapped here getchar() != EOF if you only input random text input.
The program wait for EOF - End Of File
I copied your code into a.cand compiled it using gcc a.c -o a.out
If a run ./a.out I get the behaviour you describe until I hit Ctrl+D which corresponds to EOF in my terminal.
The program will print the number of chars received once it has received EOF.
Another way to use the code is to pipe another file to it.
Create a dummy file named blaha.txtand write something in it.
You can then pipe it to the program like this:
a.out < blaha.txt
Your program waits for input and consumes it until it reaches the end of file. You can signal the end of file from the terminal by typing a special character such as control-Z followed by enter on Windows and control-D on linux and MacOS.
I'm doing homework for my C programming class. The question states "Write a program which reads input as a stream of characters until encountering EOF". I'm using Xcode on my macbook and the only way I know to make the program encounter EOF is using ctrl + D or ctrl + Z. But it will exit my program completely.
For example I have this code:
int main()
{
int ch;
while ((ch = getchar()) != EOF)
{
putchar(ch);
}
printf("%d",ch);
return 0;
}
Is there away for the code to execute the printf("%d",ch) after the loop (after i hit ctrl + D on my keyboard)?
You can test your program using (with a POSIX shell) here documents.
First compile your source code mycode.c into a binary mybin with
gcc -std=c99 -Wall -Wextra -g mycode.c -o mybin
(it could be clang or cc instead of gcc)
then run mybin with a "here document" like
./mybin << EOF
here is my
input
EOF
You could also use input redirection. Make some file myfile.txt and run ./mybin < myfile.txt
You could even run your program on its own source code: ./mybin < mycode.c
And the input could even come from some pipe, e.g. ls * | ./mybin
BTW, what you are observing is that stdin, when it is a terminal, is line-buffered. See this answer (most of it should apply to MacOSX).
Notice that your code is incorrect: you are missing an #include <stdio.h> near the top of the file, and your main should really be int main(int argc, char**argv) (BTW you could improve your program so that when arguments are given, they are file names to be read). At last the ending printf would surely show -1 which is generally the value of EOF
Also, it is much better to end your printf format control string with \n or else use appropriately fflush(3)
Notice that end-of-file is not an input (or a valid char), it is a condition on some input file stream like stdin, and the getchar(3) function is specified to return EOF which is an int outside of the range of char (on my Linux system EOF is -1 because char-s are between 0 and 255 included). You might test end-of-file condition after some input operation (never before!) using feof(3)
A terminal in usual cooked mode is handled by the kernel so that when you press Ctrl D an end-of-file condition is triggered on the file descriptor (often STDIN_FILENO i.e. 0) related to that terminal.
I'm using Xcode on my macbook and the only way I know to make the program encounter EOF is using ctrl + D or ctrl + Z. But it will exit my program completely.
No it won't. If you run your program in the Xcode debugger, provided the console pane has the focus, all input you type will go to your program (note that, by default, stdin is line buffered, so you'll only see output when you press the return key). If you hit control-d (not control-z), you're program will exit the loop and print -1 in the console window (which is what you expect because that is the value of EOF in OS X).
Here is the result when I ran your program without change in the Xcode debugger (I typed command-r in Xcode)
bgbgdfsfd
bgbgdfsfd
hgfdgf
hgfdgf
-1
Regular font was typed by me, bold font was from your program. At the end of each of the lines typed by me, I pressed carriage return. After your program printed hgfdgf I typed control-D. Your program then printed the value of the last thing it got from getchar() which was EOF which is -1 in the OS X C library.
Edit
If you are unsure that your program is printing the EOF, change your printf format string to (for example)
printf("Last character is [%d]\n", ch);
Then instead of -1 your program will output Last character is [-1] on the last line.
First of all ctrl+z does not input EOF to your program. If you hit ctrl+Z your shell will put your program to sleep.
Second, if you want to handle these ctrl+Z in your program you need to learn about signal handling in C.
And I think because you were hitting ctrl+Z you were not seeing any output on the screen.
Make sure you are sending the EOF signal, not a signal that actually terminates your program.
For example, for c program running in windows the EOF is represent by typing ctrl+z and pressing enter. Doing this will exit your while loop but still runs the rest of your program.
However, ctrl+c, which some people may have mistakenly tried for EOF, actually kills your program and will prevent the code behind your while loop from executing.
For mac you will need to find what is the input that corresponds to EOF, and make sure that is what you are sending through rather than the kill signal, which I suspect is what you are doing here.