Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am learning C language from a book called "The C Programming Language" by Brian Kernighan & Dennis Ritchie and have been stuck at its basic lesson of line counting program. The program runs but it does not give an output of how many lines were inputed.
Have given the program code below, please help on the same.
#include <stdio.h>
void main()
{
int c, nl;
nl = 0;
while ((c = getchar()) != EOF )
if (c == '\n')
++nl;
printf("%d \n", nl);
return 0;
}
The code should read the input and then output how many lines of text were given. How should this be changed to make it work?
Your program works fine. However, I would prefix main with the int type to keep the compiler quiet. It should look like this:
int main(void)
When you call it, what I did was this:
$$$ ->./test6 < test4.c
19
$$$ ->wc test4.c
19 48 379 test4.c
$$$ ->
The getchar function is the same thing as getc(stdin), so when you run your program, it takes it's input from stdin (keyboard) or a file redirected to stdin.
EDIT: As someone pointed out, if the last line doesn't have a \n terminator, that line will not be counted. So I rewrote your code to account for this:
#include <stdio.h>
int main(void)
{
int c; /* Character */
int cp; /* Previous Character */
int n; /* Number of lines */
n = 0;
c = 0;
while (1)
{
cp = c;
c = getchar();
if (c == '\n')
{
n++;
continue;
}
if (c == EOF && cp == '\n') break;
if (c == EOF)
{
n++;
break;
}
}
printf("%d \n", n);
return 0;
}
As you can see in the code, I used fall-though logic to either continue the loop or to break out of it. Now I tested this code using clang on FreeBSD and it works properly.
The logic of this program is as follows:
Save current character as the previous character.
Get the next character and make it the current character.
Check the current character to see if it's a newline character.
If it is, then we increment the line counter and restart the loop.
Check the current character to see if it's EOF and the previous character to see if it's the newline character.
If it is, then break out of the loop.
Check the current character to see if it's EOF.
If it is, then increment the line counter and break out of the loop.
That is how you deal with the final line not being terminated by a newline character and still have it counted as a line. Note that this is considered a special case and needs to be explicitly coded for. If you continue into the software development profession, then you will encounter special case situations a lot and you need to code the handling for each one that you encounter.
Hope this helps.
There was no issue with code; it work's fine, only the issue- it was taking input and was not giving output.
In windows to end input,
we have to press Ctrl + Z followed by Enter key, it will show the count of lines in input.
Your code is working properly.I checked it in Ubuntu.
Just press Ctrl+d if you are working in Linux to end the input.
Related
This question already has answers here:
How to enter the value of EOF in the terminal
(4 answers)
Closed 2 years ago.
I recently started learning C from The C Programming Language by Brian Kernighan and Dennis Ritchie. In that book, there's a whole subsection (1.5.1, 2nd Ed.) where the authors create a file copying program (but I am using this as a text (input by the user) copying program). Their code basically looks like this
#include <stdio.h>
int main()
{
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
}
This code works fine when run, but the program never stops. The program keeps on waiting for inputs and goes on copying them, endlessly, never terminating. Now I wanted to create a program where this endless copying does terminate. To do so, I tweaked the code a little bit. Here's my code
#include <stdio.h>
int main()
{
int c;
c = getchar();
while (c != EOF) {
putchar(c);
c = getchar();
}
return 0;
}
I thought that explicitly writing return 0; at the end might do the job, but it seems that the output doesn't change at all. I also tried using if-else conditions and looping them as follows
#include <stdio.h>
int main()
{
int c;
c = getchar();
while (1) {
if (c != EOF){
putchar(c);
c = getchar();
}
else
return 0;
}
}
But the program didn't change at all in this case as well.
My question is that how do I change the code so that my program ends just after copying once (or, even better, generalising it to copying n times)?
Here, it is important for me to clarify what I mean by "once" (or "n times" for that matter). When I use the command prompt (I use Windows) to run the compiled file, the program expects an input. I enter the input through my keyboard, and then press Enter to see the reproduced input. After this, the program again expects me to enter some input. I don't want this to happen. I want the program to end by itself after it copies my input once. This is what I mean by "once" (and the above definition can easily be extended for "n times" as well).
#anatolyg and #Jabberwocky have suggested the use of \n (new line escape character) to make the program work. But this solution fails when the input contains linebreaks, for example
my code does
not work so
I am asking
for help here
Copying this into the command prompt as the input, and using the program suggested by the above two users yields only my code does as the output, which is not what I wanted as an output. Is there any way I can make this program work for text blocks with linebreaks and also make it stop after one input (in this case, the whole text block is just one input)?
After interacting with the other people here, I have come to realise that my definition of "one input" or "once" is quite vague, unclear and not at all concrete. Thus it is nothing but expected that C cannot do what I want it to do. I am accepting the answer which suggests to use the new-line escape character as a signal to terminate the program, because that is the closest to what I had in my mind. Thank you all.
Your return 0 won't make any difference as the execution will stay in the while until c becomes EOF. So you need to make c equal to EOF. Try ctrl-D or ctrl-Z depending on OS.
My question is that how do I change the code so that my program ends just after copying once (or, even better, generalising it to copying n times)?
Introduce a counter like:
#define MAX_INPUTS 10
...
int cnt = 1;
while (c != EOF && cnt < MAX_INPUTS) {
putchar(c);
c = getchar();
++cnt;
}
For starters this loop
while (c != EOF) {
putchar(c);
c = getchar();
}
is not endless. There is a condition in the while loop that if it is not satisfied the loop terminates.
To generate the output of the function getchar equal to EOF you should enter the key combination Ctrl + c in Windows or Ctrl + d in an Unix system.
Adding a return statement either in the body of the loop or after the loop does not principally influence on the program control flow.
Pay attention to that the return statement in main may be omitted. From the C Standard (5.1.2.2.3 Program termination)
1 If the return type of the main function is a type compatible with
int, a return from the initial call to the main function is equivalent
to calling the exit function with the value returned by the main
function as its argument;11) reaching the } that terminates the main
function returns a value of 0.
So for example these two programs
int main( void )
{
return 0;
}
and
int main( void )
{
}
are valid and equivalent.
Since you want to read only one line of input, you can terminate the loop on the end-of-line character '\n'.
c = getchar();
while (c != '\n') {
putchar(c);
c = getchar();
}
If you use a Windows terminal to enter data to your program, this will be enough. If you redirect the input to your program, so that it comes from a file, it will read the file up to the first newline character. However, if the file contains no newline character, your program will get EOF at end of file. So the terminating condition should also check for EOF.
c = getchar();
while (c != '\n' && c != EOF) {
putchar(c);
c = getchar();
}
If you want to read the first n lines from the file/terminal, you need a counter. Then your code will become a bit more complicated, and I think an endless loop with exits in the middle would be a better implementation.
int line_counter = 0;
int max_lines = 5;
while (1) {
int c = getchar();
if (c == EOF)
break;
putchar(c);
if (c == '\n')
{
++line_counter;
if (line_counter == max_lines)
break;
}
}
Another method for separating between inputs is with an empty line. This redefines input format to have "paragraphs" of text. This will complicate the code a little more - it should also hold the previous character it read. To detect an empty line, which marks the end of a paragraph: if both previous and current character are end-of-line characters, the paragraph of text has just ended.
int record_counter = 0;
int max_records = 5;
int prev_c = '\n';
while (1) {
int c = getchar();
if (c == EOF)
break;
putchar(c);
if (prev_c == '\n' && c == '\n')
{
++record_counter;
if (record_counter == max_records)
break;
}
prev_c = c;
}
Ypur latest edit suggests you might want something like this:
#include <stdio.h>
int main()
{
int c;
c = getchar();
while (1) {
if (c != EOF && c != '\n') { // '\n' is End of line (Enter)
putchar(c);
c = getchar();
}
else
return 0;
}
}
or simpler:
int main()
{
do
{
int c = getchar();
if (c != EOF && c != '\n') { // '\n' is End of line (Enter)
putchar(c);
}
else
{
return 0;
}
} while (1);
}
This code works fine when run, but the program never stops.
This is not true, if you don't satisfy the condition of the while statement:
while (c != EOF)
the program will terminate.
Now how you can send EOF to the input?
Depends. Which stdin operation are you trying to EOF? If stdin is terminalinput just press control-D. If the ONLY thing you want to send is EOF, use echo -n | (your program). If you are sending it FROM your C program, you are pretty much stuck with exiting from the program, at which point the state of its stdout will be EOF, which will in turn be reflected in whichever stdin it was redirected to. I'm pretty sure you can't just send EOF from within C without getting a hold of an underlying buffer, which aren't standardized, and therefore would leave you with some dirty programming to do.
Another solution is check in or some digitable character in the while condition for example:
#include <stdio.h>
int main()
{
int c;
c = getchar();
while (c != EOF && c!= 'A') {
putchar(c);
c = getchar();
}
}
in this case if you digit "A" the program will ends up.
The function getChar() in this case is always waiting for the new character, and in this case c is never to get the EOF value. You can set a character to finish (for example 'e' to exit) or you can count with a counter as you say to exit the loop. Do not use while(1) because is not a good practise.
This question already has answers here:
Problem with example 1.5.2 in K&R book on C
(5 answers)
Closed 2 years ago.
i was practicing the line counting program. I'm a little bit confused how should i be giving input to this program. I tried typing random sentences including '\n' - the new line element inside my program. But no matter what output i give , the output is still blank and asking me to keep typing. I've went through Internet for a while , and i couldn't figure out where i failed. Can you help me please. I was going to skip this lesson and come back again. But the later lessons of the text book depends on this topic . Thanks
#include <stdio.h>
/* count lines in input */
main()
{
int c, nl;
nl = 0;
while ((c = getchar()) != EOF)
if (c == '\n')
++nl;
printf("%d\n", nl);
}
So, the output is still blank because your program's stuck at a while loop, since the code beneath it is not between curly brackets ({}), that way, your program is asking for input characters indefinitely with no outputs as a result.
Also, I was a little confused by your code since I didn't how to get to EOF through stdin without using file redirection. And by searching through Stack Overflow I've found out that you need to type Ctrl+D, at UNIX-based systems, or Ctrl+Z, on Windows, in order to use EOF through console typing.
(End of File(EOF) of Standard input stream (stdin))
By the way, I've modified your code, I just don't know if that was exactly what you were trying to do:
#include <stdio.h>
/* count lines in input */
main()
{
int c, nl;
nl = 0;
while ((c = getchar()) != EOF)//EOF can be reached by stdin when pressing Ctrl+D
{
if (c == '\n')
{
++nl;
}
}
printf("Number of lines: %d\n", nl);
}
Good coding!
This question already has answers here:
What is EOF in the C programming language?
(10 answers)
Closed 5 years ago.
I am new to coding and I am learning through a book called "The C Programming Language - 2nd Edition - Ritchie Kernighan" and there is this code:
#include<stdio.h>
#include<stdlib.h>
int main(){
int c,nl;
nl =0;
while((c=getchar())!=EOF)
if(c == '\n')
++nl;
printf("%d\n",nl);
return 0;
}
After typing the code in CodeBlocks I run it and when I type in a word and press enter nothing happens. The word is not being counted and printed. I am new to all of this but if anyone has an idea feel free to share it. Thank you very much !
The issue is that you never read the EOF (End Of File); this is the end of the input data coming from the console (where you type).
Everything you type is either a letter, digit, special character, or newline, but never EOF.
To generate an EOF you need to enter a special control-key combination. On Windows this is Ctrl+Z and on UNIX/Linux/macOS this is Ctrl+D.
The book you're reading is great and written by the two creators of C. It one of my first programming books and I still have it; all worn-out.
Small piece of advice: Always put your code blocks inside { } to avoid mistakes and create more visual clarity, use spaces consistently, and add empty lines. Your code would look like this:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int c, nl;
nl = 0;
while ((c = getchar()) != EOF)
{
if (c == '\n')
{
++nl;
}
}
printf("%d\n", nl);
return 0;
}
Why should it stop? Your expectations are wrong. getchar() will go on getting characters until it encounters EOF.
How to pass that to getchar?
For Windows Ctrl+Z will do the trick. And then press Enter.
For Unix or Linux system it would be Ctrl+D
Responsive output before entering EOF
To get a more responsive output you can add this line, that will tell you the cumulative sum of \n found.
if(c == '\n'){
++nl;
printf("Till now %d newline found",nl);
fflush(stdout);
}
Further Explanation of the added code
The code segment provided above will provide you some output when you press enter. But the thing is until you enter EOF it will keep on waiting for more and more input. That's what also happened in the first case. So you have to press Ctrl+Z and press Enter. That will break the loop. And you will see the final output - the number of line count.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I wrote the following code as part of an exercise in chapter one of K&R. The code replaces tabs and backslashes as expected, but it does not replace backspaces with \b. Here is the code:
#include <stdio.h>
int main(void)
{
int c;
while((c = getchar()) != EOF)
{
if (c == '\t')
{
putchar('\\');
putchar('t');
}
if (c == '\b')
{
//putchar('\\');
//putchar('b');
printf("\\b");
}
if (c == '\\')
{
putchar('\\');
putchar('\\');
}
if (c != '\t' && c != '\b' && c != '\\')
{
putchar(c);
}
}
return 0;
}
I've looked through Stack Overflow. The answers to this question talk about the shell's consuming the backspace, the result being that code I write never sees the backspace. This brings me to my question: what happens to the input I provide at the keyboard? I assume this becomes part of the stdin stream. Clearly, though, not all the characters I enter make it to my code. Can someone please explain what processing happens between my keystrokes and the handling of that input by my code? Also, is there a way for my code to read the stdin buffer before this processing occurs?
I hope these questions make sense. It took me a while to figure out what I am trying to ask, and I'm not sure I've figured that out completely.
When getchar() is reading from an interactive console, the function won't return until after you press the ENTER key. Then it will return with the first character entered, and immediately return for each subsequent character you entered up to a newline character.
If you pressed backspace, delete, or an arrow key prior to pressing ENTER, the terminal processes those keystrokes and will only send the "final result" when you press ENTER.
Had you been reading from a redirected-in file (i.e. you called you program as ./myprog < input_file) or piped output from another program (i.e. ./otherprog | ./myprog), then getchar would return right away for each character and you would see everything, including control characters and individual UTF-8 bytes.
That's because the backspace character never gets to getchar in standard input. When you type backspace, it just cancels the character you just typed.
If you manage to create a text file with backspace characters and feed it to your program that will work, though.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I just started programming and came up with a program to count the number of characters in an input.
The code is as below:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int number = 0;
int counter = 0;
char sentence[20];
printf("Enter a sentence: ");
scanf("%s", sentence);
while ( sentence[number] != '\n' )
{
counter += 1;
number += 1;
}
printf("no. of characters in sentence you just typed: %d", counter);
return 1;
}
This program has a strange behavior that I cannot understand. It compiles without error but no matter how many characters I type or what character is entered, it shows the no. of characters as 817.
I am curious as to why 817? It's really weird. Also please enlighten me on how I can improve my code since it did not perform as expected.
scanf reads input till \n but not including it So :
while ( sentence[number] != '\n' ) // always true for legal array bound
will lead to illegal memory access, causing undefined behavior. If you do wish to read the string including the [ white-space ] characters, use [ fgets ].
If you wish to count the number of characters, change the while loop to
while ( sentence[number] != '\0' )
scanf with the argument "%s" reads one word, up to the first space or tab or newline, and will not include any \n character in the input. Your loop will never end. Or, more accurately, it will give what the C standard calls "undefined behaviour". In practice, it means that it will keep looping until it either finds a newline somewhere in memory (perhaps 817 places from the start!), or reaches the end of allocated memory and crashes.
If you read the manual page the function scanf does not read white space.
Perhaps fgets would be a better choice along with changing the while loop to
while (sentence[number] != 0 && sentence[number] != '\n')
Just change this line :
while ( sentence[number] != '\n' )
to
while ( sentence[number] != '\0' )
and return 0 at the end
Here is a better version of code to count the number of characters
#include <stdio.h>
main(){
double c;
for(n=0; getchar() != EOF; ++n);
printf("%.0f\n", n);
}