Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
|
|
01-07-2003, 12:20 PM
|
#1
|
Senior Member
Registered: Jan 2002
Location: Rome, Italy ; Novi Sad, Srbija; Brisbane, Australia
Distribution: Ubuntu / ITOS2008
Posts: 1,207
Rep:
|
getchar()
Im learning C (yes again!) and by following some examples in the book, i wrote two programs (exactly the way they are in the book) but im not happy with their output. Here are the programs, they should be self explanatory:
#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);
}
and the second one
/* Count characters in input, 1st version */
#include <stdio.h>
main ()
{
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
}
They compile ok, but the printf() lines are never executed. This is waht i get when pressing random keys (and enter) while running the program:
|:-(Tue Jan 7 16:26:39)-(nskl@Slackbox:~)$ ./a.out
d
f
dgf
h
hj
f
dsf
z
and i have to ctrl-C out of it. So how do i get out of getchar(), i thought it was like with scanf() when i press enter the program flows on. Im confused yet again why printf() line is never executed, or how to send EOF to getchar() so the program can flow on.
Thanks
-NSKL
Last edited by NSKL; 01-07-2003 at 12:27 PM.
|
|
|
01-07-2003, 01:04 PM
|
#2
|
Moderator
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,417
|
well you have a while loop that just loops... there's no block - { and } to contain the acutal instructions, so it's jsut the ++nc that's being exectued infinitely.
|
|
|
01-07-2003, 01:06 PM
|
#3
|
Senior Member
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536
Rep:
|
Quote:
Code:
while ((c == getchar()) != EOF)
|
This line should read:
Code:
while ((c = getchar()) != EOF)
/* One '=' less before getchar() */
This could explain why the loop doesn't end. However the second program looks correct to me.
Anyways you will need to know how to have the program read an EOF.
Three ways to do this:
(1) Send a text file through a pipe to your a.out, instead of pressing keys after running your a.out. After the whole file is processed by your program, an EOF is sent automagically:
$ cat /etc/passwd | ./a.out
(2) Run ./a.out like you have done already and press CTRL-d when done entering text. CTRL-d sends an EOF.
(3) Use the shell contruction called "here document":
$ ./a.out << QQQ
this is the text you
are typing to get it processed
by your program
QQQ
Good luck!
|
|
|
01-07-2003, 01:10 PM
|
#4
|
Senior Member
Registered: Sep 2002
Location: Arizona, US, Earth
Distribution: Slackware, (Non-Linux: Solaris 7,8,9; OSX; BeOS)
Posts: 1,152
Rep:
|
Oh, boy. . .
Ok, first, you don't really have a while *LOOP*, you have a
single while statement. You need to enclose the statements in
curly brackets
while (getchar() != EOF)
{
++nc;
printf("%ld\n", nc);
}
However, getchar() doesn't really seem to be what you want.
Using getchar(), you get the following output from the above
code:
./countc
a
1
2
b
3
4
c
5
6
d
7
8
This is because you are reading in two characters ("a\n" is not a
single character), and so it increments nc twice.
for the countlines, you have several problems:
You don't want c to be an int, you're checking to see if c is
equal to the output of getchar, so you never actually assign a
value to c, so checking to see if c is the new line character
doesn't ever work (unless you happen to hit a memory spot
that causes this to come true).
Just some hints. . . Get a different book.
Last edited by moses; 01-07-2003 at 01:11 PM.
|
|
|
01-07-2003, 01:10 PM
|
#5
|
Senior Member
Registered: Sep 2002
Location: Arizona, US, Earth
Distribution: Slackware, (Non-Linux: Solaris 7,8,9; OSX; BeOS)
Posts: 1,152
Rep:
|
damn!
hungry kid caused me to be late in posting. . .
=-}
|
|
|
01-07-2003, 01:11 PM
|
#6
|
Member
Registered: Jan 2003
Posts: 56
Rep:
|
try typing ctrl-d, this is equivalent to end of file, it should stop the loop
|
|
|
01-07-2003, 01:18 PM
|
#7
|
Senior Member
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536
Rep:
|
Quote:
Ok, first, you don't really have a while *LOOP*, you have a
single while statement. You need to enclose the statements in
curly brackets
|
No, not necessarily. If there is only one statement in the while loop (and that the case here), it's OK to not have the curly brackets. Same goes for the if statement inside the while in the first code.
The code listings are correct. Except for one '=' too much (see my first reply)
Quote:
You don't want c to be an int [..snip..]
|
Not true. Actually an int is more correct here, for getchar() does return an int, not a char. See the man page.
Last edited by Hko; 01-07-2003 at 01:19 PM.
|
|
|
01-07-2003, 01:42 PM
|
#8
|
Senior Member
Registered: Jan 2002
Location: Rome, Italy ; Novi Sad, Srbija; Brisbane, Australia
Distribution: Ubuntu / ITOS2008
Posts: 1,207
Original Poster
Rep:
|
Ah! Now im so lost, some people say one thing, others say other. The book is K&R "The C programming Language" Anyway i will revise my programs according to your suggestions and i'll try figuring the rest by myself, and whoah! 6 replies in less than an hour.
I really appreciate your help everyone
thank you
-NSKL
EDIT: I did as suggested and now the programs work the way they should, but damn, K&R is supposed to be a good book, but if examples in it dont work that makes it, lets put it, "less good". And just not to make a fool of myself, i checked for 50th time, and the programs are written in the book the way i posted them above, except a double == on one place.
Thank you again everyone
-NSKL
Last edited by NSKL; 01-07-2003 at 01:51 PM.
|
|
|
01-07-2003, 02:01 PM
|
#9
|
Moderator
Registered: Jun 2001
Location: UK
Distribution: Gentoo, RHEL, Fedora, Centos
Posts: 43,417
|
maybe it was a test...?
|
|
|
01-07-2003, 02:24 PM
|
#10
|
Senior Member
Registered: Jan 2002
Location: Rome, Italy ; Novi Sad, Srbija; Brisbane, Australia
Distribution: Ubuntu / ITOS2008
Posts: 1,207
Original Poster
Rep:
|
Dont think so, it introduces new concepts in the program, and its on the beggining of the book (page 19).
Still i read another C book, "C for absolute beginners" and although K&R book is much more complex, packs more knowledge in less pages, i find it very good. It also gives Exercises so you can test what you have learned. But i immgine you already have this book so theres no point describing it.....
Thanks again
-NSKL
|
|
|
01-07-2003, 03:40 PM
|
#11
|
Senior Member
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536
Rep:
|
Quote:
K&R is supposed to be a good book, but if examples in it dont work that makes it, lets put it, "less good".
|
Just don't worry. There's nothing wrong with the book. It's K&R for heaven's sake! And there's nothing wrong with the code examples. They work, right?
In fact it was just that you didn't know how to send an EOF from the shell.
K&R is a good book
|
|
|
01-07-2003, 03:51 PM
|
#12
|
Senior Member
Registered: Jan 2002
Location: Rome, Italy ; Novi Sad, Srbija; Brisbane, Australia
Distribution: Ubuntu / ITOS2008
Posts: 1,207
Original Poster
Rep:
|
Are you trying to convince me or yourself
I like the book as i said in my previous post, it's just that the poor guys forgot a pair of {}, no biggie.
It's incredible how much stuff they packed in 250 pages. I read one section then take an hour to "digest" it then proceed. It'll take me forever to finish the book, but im sure it's worth it.
Thanks again for all the help
-NSKL
|
|
|
01-07-2003, 06:30 PM
|
#13
|
Senior Member
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536
Rep:
|
Quote:
Are you trying to convince me or yourself
|
None of the above. :-) I'm really absolutely 100% sure.
This time I even pasted both your code examples into vi, removed the '=', compiled and ran them.
I even compared the output of the programs with the wordcount utility "wc", and your programs have the same result as:
$ wc -l /etc/passwd
$ wc -m /etc/passwd
Quote:
I like the book as i said in my previous post, it's just that the poor guys forgot a pair of {}, no biggie.
|
No, they didn't.
Third time: The code is correct.
So is this one (though stupid and useless: it just exits):
Code:
int main()
{
while (1) while (1) while (1)
if (1) if (1) return 0;
}
Last edited by Hko; 01-07-2003 at 06:47 PM.
|
|
|
01-08-2003, 01:35 PM
|
#14
|
Senior Member
Registered: Jan 2002
Location: Rome, Italy ; Novi Sad, Srbija; Brisbane, Australia
Distribution: Ubuntu / ITOS2008
Posts: 1,207
Original Poster
Rep:
|
Ok, sorry, i didnt realize.
I still don't understand tho.
This:
/* Count characters in input, 1st version */
#include <stdio.h>
main ()
{
long nc;
nc = 0;
while (getchar() != EOF)
++nc;
printf("%ld\n", nc);
}
and this
/* Count characters in input, 1st version */
#include <stdio.h>
main ()
{
long nc;
nc = 0;
while (getchar() != EOF) {
++nc;
printf("%ld\n", nc);
}
}
Are different, because the first one, which is exactly as in the book, does not report the characters in input, while the second one does, when { } is added. Now, the program is supposed to report characters in input, but the first one never does, because printf() is never executed, thus the example doesn't work.
Now im a newbie, so i might be well wrong like before, if so please correct me, and sorry for this wasting of your time.
Thanks
-NSKL
|
|
|
01-08-2003, 06:08 PM
|
#15
|
Senior Member
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536
Rep:
|
I didn't realize that it still didnt work for you. Sorry, about that.
Like I said, I compiled them, and they both worked for me.
But there there is a difference between the two programs you listed in your last post. The output is different. Maybe you think the first is not working, because you expect a different output. It acutally does execute the printf() and outputs the number of characters.
I'll try to explain.
The first one counts all input character's in memory, using the variable nc. And only after reading all of the characters it outputs only one number, which is the number of counted characters.
It does not output anything as long the program did not read an EOF.
The second program outputs the number of characters after every line (when the <ENTER> key is pressed). And it does so, while counting.
Try changing the first program, to make its output more noticable:
printf("\n\nCounted %ld characters.\n\n", nc);
Use CTRL-d to send a EOF and see what happens. It has counted all characters you entered, but it outputs only one number. And that, I'm quite sure what the authors of the progam ment it to do.
There is a utility on your linux system called "wc" (WordCount), which can be used to count character, words, lines and the longest line, depending on the switches you give it on the command line.
Maybe the effect of the program is more clear to you when you have these programs count characters/lines from a file. Then do the same with "wc -m" to compare the results. Here's the shell session I am talking about on my computer:
Code:
$ cat /etc/passwd | ./a.out
Counted 1209 characters.
$ cat /etc/passwd | wc -m
1209
So the file /etc/passwd contains 1209 characters.
If do the same with your version with the { } then it ouputs 1209 lines with increasing numbers from 1 to 1209. This is because that program outputs while counting.
The difference between the first and second program (of your last post) is that the printf() is included in the while loop!
To have both codes equivalent, the second one should read:
Code:
main ()
{
long nc;
nc = 0;
while (getchar() != EOF) {
++nc;
}
printf("%ld\n", nc);
}
Note that the } is now above the printf(), and it works exactly the same as the version from the book, without { } . And I believe this is the way it K&R meant it to work.
In C, whitespace (space, tab, enter/return) don't make difference. So the following loops are equivalent:
Code:
/* --1-- */
while (getchar() != EOF) ++nc;
/* --2-- */
while (getchar() != EOF)
++nc;
/* --3-- */
while (getchar() != EOF) {
++nc;
}
There's one more thing to wonder about. With the printf() included in the while loop (your second code), one would expect it outputs the number of character directly after each character read. You anly notice this when you are typing the input into the program instead of feeding it the contents of a file with "cat", see above.
This doesn't happen because UNIX (and linux as well) buffer input by lines. So the terminal waits until it receives a linefeed (ENTER key) and the the terminal sends the whole line at once to your program.
This behaviour can be changed, from the shell as well as from a program, but that's quite beyond this subject.
I hope this help. Have fun!
Last edited by Hko; 01-08-2003 at 06:16 PM.
|
|
|
All times are GMT -5. The time now is 10:01 PM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|