Newb Question Character Counting

This is a discussion on Newb Question Character Counting within the C Programming forums, part of the General Programming Boards category; First of all as the title suggest I am a newb. I pretty much just started to try and teach ...

  1. #1
    Registered User
    Join Date
    Jun 2008
    Posts
    5

    Newb Question Character Counting

    First of all as the title suggest I am a newb. I pretty much just started to try and teach myself C, and I would like you to help me if possible.

    I am trying to create a small program that counts characters. I am following along in a book and I entered the code exactly as it says, but it doesn't work like it should (it does compile though). I'll post the code below.

    Code:
    #define EOF -1
    
    main ()
    {
    	long nc;
    	
    	nc = 0;
    	while (getchar() != EOF)
    		++nc;
    	printf("%1d\n", nc);
    }
    Like I said it compiles fine and that is what the book says works. I think the problem is that its getting stuck in the while statement and thus will never actually get to the printf function. I tried myself before posting to try to arrange it in a way that would work, but couldn't seem to figure it out. Like I said I'm a newb to C (along with programming in general) so any help is greatly appreciated.

  2. #2
    int x = *((int *) NULL); Cactus_Hugger's Avatar
    Join Date
    Jul 2003
    Location
    Banks of the River Styx
    Posts
    902
    You need to send a EOF. Either pipe a file in through stdin, like:
    Code:
    cat somefile.txt | yourprogram
    Or, if you're on Windows
    type somefile.txt | yourprogram
    Or, send an EOF. I believe it's Ctrl+Z, but I could be wrong.

    Edit: Also, main() returns an int! Make it such!
    Code:
    int main()
    {
        // ... code ...
        return 0;  // or some nonzero number if errors occur.
    }
    long time; /* know C? */
    Unprecedented performance: Nothing ever ran this slow before.
    Any sufficiently advanced bug is indistinguishable from a feature.
    Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
    The best way to accelerate an IBM is at 9.8 m/s/s.
    recursion (re - cur' - zhun) n. 1. (see recursion)

  3. #3
    Registered User
    Join Date
    Jun 2008
    Posts
    5
    Thanks, pretty sure I understand now.

  4. #4
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,537
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    Quote Originally Posted by Cactus_Hugger View Post
    Or, send an EOF. I believe it's Ctrl+Z, but I could be wrong.
    Note that on Unix and Unix-like system, the right combination of key is Ctrl+D, where in Windows, it's Ctrl+Z.

    Oh and Wilder, don't forget to include stdio.h in your source file (#include <stdio.h>) and remove that line where you define EOF.
    I hate real numbers.

  6. #6
    Registered User
    Join Date
    Jun 2008
    Posts
    5
    I changed the code around a little bit so it is now:

    Code:
    #include <stdio.h>
    
    main()
    {
    	long nc;
    	
    	nc = 0;
    	while (getchar() != EOF)
    		++nc;
    	printf("&#37;1d\n", nc);
    	while (1 != 0) // Only here so that the DOS window doesn't close automatically 
    		;      // so I can view the result. 
    }
    After I finish typing the characters that I want counted I have to push CTRL+Z then enter and it will display the correct result. My next question is there anyway I can arrange it so that after I push enter it will count the characters I typed so that I don't need to do CTRL+Z? Like I said before I'm new to C, but I'm guessing where it says while (getchar() != EOF) I would change EOF to whatever the value for enter would be?

  7. #7
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,537
    Last edited by Elysia; 06-22-2008 at 09:54 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    My next question is there anyway I can arrange it so that after I push enter it will count the characters I typed so that I don't need to do CTRL+Z? Like I said before I'm new to C, but I'm guessing where it says while (getchar() != EOF) I would change EOF to whatever the value for enter would be?
    Bingo! And that is: '\n'. With the single quotes and all.

    Or you could use a function that does it all for you, like fgets(), as Elysia suggested. Personally, I wouldn't, though; you're just counting characters, after all, so reading one character at a time makes more sense than reading a whole line all in one go . . . .

    Also: the "1" in &#37;1d is entirely optional. This works just fine.
    Code:
    printf("%d\n", nc);
    Code:
    	while (1 != 0) // Only here so that the DOS window doesn't close automatically 
    		;      // so I can view the result.
    That works, it's true. (Though there are shorter ways, most notably while(1) and for(;;).)

    However, it uses 100% of your processor, so it's not ideal. You could put another getchar() in there to wait for a key to be pressed, but I don't think that would work after you type EOF, so only try this once you have the '\n'/fgets() thing working.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #9
    Registered User
    Join Date
    Jun 2008
    Posts
    5
    Thanks for the help, I really appreciate it. The program now works just like I want it to. Final code is:

    Code:
    // Counts the number of characters in the input
    #include <stdio.h>
    
    int main()
    {
    	long nc;
    	
    	nc = 0;
    	printf("Please type a phrase then press ENTER to see how many charcters it has.\n\nInput: ");
    	while (getchar() != '\n')
    		++nc;
    	printf("\nThe input has &#37;d characters.\n\nPress ENTER to exit", nc);
    	getchar(); // Used to prevent DOS window from closing automatically
    	return 0;
    }
    The getchar() at the end now works as a way to stop DOS window from exiting automatically now that I'm not using the EOF which works much better. Once again thanks for all the help.
    Last edited by Wilder; 06-22-2008 at 11:33 PM.

  10. #10
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,537
    Do you even read links that are posted?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    Well, because it was just a bare link with no explanation, you could think by accident that it was related to fgets() . . . .

    But still, Elysia is right, of course. You should use "int main()" and add a "return 0;" statement to the end of main(). The way you have it is relying on the implicit int rule, which is deprecated. But I'm sure I'm just repeating Elysia's link, which I urge you to read.

    http://cpwiki.sourceforge.net/Implicit_main

    [edit] I just know it's going to start a "main" debate, but int main() is actually a better idea than int main(void), because main() is going to be passed some parameters whether you like it or not, and stating int main(void) tells the compiler that no parameters will be passed, while int main() says that anything could be passed. At least, this is what someone said in the last debate. (Was it brewbuck?) I don't buy into it, myself . . . . [/edit]
    Last edited by dwks; 06-22-2008 at 11:17 PM.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  12. #12
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,537
    Quote Originally Posted by dwks View Post
    [edit] I just know it's going to start a "main" debate, but int main() is actually a better idea than int main(void), because main() is going to be passed some parameters whether you like it or not, and stating int main(void) tells the compiler that no parameters will be passed, while int main() says that anything could be passed. At least, this is what someone said in the last debate. (Was it brewbuck?) I don't buy into it, myself . . . . [/edit]
    I don't really have many arguments there. Either one is acceptable to me.
    Just not implicit main.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Registered User
    Join Date
    Jun 2008
    Posts
    5
    Ok i edited it a bit. Should be all right now?

  14. #14
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    Perfect! Well, just about . . .

    &#37;d is for ints; nc is a long. nc should either be an int, or you should use the format specifier for longs: %ld.
    Code:
    printf("%ld\n", nc);
    There's only one other thing with it that I can see which might cause some trouble: the printf() statement at the end. It doesn't end with a newline.

    You see, consoles are typically line-buffered; that is, they might only display what you've printed to them when you print a newline. So, in some cases, your message might not be printed.

    You could fix this by ending the printf with a newline, which I would recommend.

    You could also use fflush(stdout) to force the output to be written to the screen, but that's probably just too complicated for something that probably will never happen.

    [edit] This "buffer" thing needs elaboration.

    With files and other sources of input and output, it's generally inefficient to read just one character at a time. For this reason, the operating system often reads or writes data in largish chunks. When you write one character to a file, it's stored in a buffer instead of being written immediately. When this buffer gets full, then, and only then, is the data written to the file. It's more efficient this way.

    Unfortunately, this can cause some trouble for us programmers. For example, if you terminate a program that is writing to a file, the latest changes might not have been written to the file. In your case, data you write to the screen might not be visible unless you print a newline. But buffering is still a good thing. Your computer would be very slow without it.

    Fortunately, you can force whatever's in the buffer to be written to the file or to the screen immediately. Which I indicated, with fflush(). Since the screen is line-buffered, you can also just print a newline to force the buffer to be flushed. [/edit]
    Last edited by dwks; 06-22-2008 at 11:44 PM.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. need help with 'character counting from a .txt file'
    By master_vst in forum C Programming
    Replies: 5
    Last Post: 11-09-2008, 01:17 PM
  2. Newb question - Clear command line screen?
    By Fujimitsu in forum C Programming
    Replies: 3
    Last Post: 04-12-2008, 01:47 PM
  3. Just a quick question about character arrays
    By Welshy in forum C Programming
    Replies: 3
    Last Post: 04-03-2006, 07:20 AM
  4. UNICODE and GET_STATE
    By Registered in forum C++ Programming
    Replies: 1
    Last Post: 07-15-2002, 03:23 PM
  5. Character counting program
    By TankCDR in forum C++ Programming
    Replies: 5
    Last Post: 04-05-2002, 09:01 PM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21