Thread: Need Help making my first while loop.

  1. #1
    Registered User
    Join Date
    Oct 2012
    Posts
    33

    Need Help making my first while loop.

    I've been assigned a program requiring loops. The program's objective is to read and tally certain letters of baseball player record. The txt file looks like this:

    12 HOOPSTOHOPST
    4 OSPSHOOSOPSPPSH
    7 OOHOSPHPPSHHOSPW

    The numbers are the player numbers.

    The assignment requires a program that calculated average batting score, which are just the sum of Hs and Ps divided by the total number of letters.

    So I've been trying to make a loop that simply reads and displays the player's number and record

    Code:
      # include <stdio.h>  2
      3 int main (int argc, char *argv[] )
      4
      5 {
      6     int player;
      7     char at_bat;
      8     FILE *fp;
      9
     10     fp = fopen( argv[1], "r" );
     11     fscanf(fp, "%c", &at_bat);
     12
     13     while ((fscanf(fp, "%d",  &player)) != EOF)
     14     {
     15     printf("Player number is %d.\n", player);
     16     fscanf(fp, "%c", &at_bat);
     17     printf("_%c_", at_bat);
     18        while ((fscanf(fp, "%c", &at_bat)) != '\n')
     19        {
     20        fscanf(fp, "%c", &at_bat);
     21        printf("%c", at_bat);
     22        }
     23     }
     24     return(0);
     25 }
    My program cycles endlessly and prints no text. How can I get this loop to just print out the txt file using a loop? I'm sure if I could get fimiliar with the format of while, I could handle the math. Am I using the EOF correctly? Please help me. - Thanks for your time. - Kurt
    Attached Files Attached Files
    Last edited by Kurtanius21; 10-23-2012 at 01:32 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Your at_bat code is very suspect though.
    You have 3 separate fscanf calls, but you should only need one.

    Perhaps
    Code:
    while ( (fscanf(fp, "%c", &at_bat)) == 1 && at_bat != '\n')
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Minor issue to clear up first, don't copy line numbers when you post here, our forum will do it for you. And you don't need to attach the .c file either. Actually, lots of people wont download attachments.

    Next, you should always check the return value of fopen. If it fails (returns null), you should print a useful error message (look into the perror() function, or strerror() with errno).

    Then, read the fscanf documentation (link). You're using the function correctly, but not handling the return value correctly. You should always check the return value against the number of things you asked it to scan/convert. That is, the number of "%d", "%c", "%s", etc things in your format string. For you this is 1. It's possible that fscanf will return 0 on fail instead of EOF. You don't handle that in your loops. Also, fscanf will only return '\n' if you ask for 10 things, and they all convert*. Try something like:

    Code:
    while (fscanf(fp, "%d", &player) == 1) {
        ...
        while (fscanf(fp, "%c", &at_bat) == 1 && at_bat != '\n') {
        }
    }
    * And even then, that is only true if you're using a character set where a new line ('\n') has a integer value of 10, such as ASCII or compatible sets.

  4. #4
    Registered User
    Join Date
    Oct 2012
    Posts
    33
    Quote Originally Posted by anduril462 View Post
    Code:
    while (fscanf(fp, "%d", &player) == 1) {
        ...
        while (fscanf(fp, "%c", &at_bat) == 1 && at_bat != '\n') {
        }
    }
    * And even then, that is only true if you're using a character set where a new line ('\n') has a integer value of 10, such as ASCII or compatible sets.
    How then can I know if the new line returns a value of ten? And when you say the fscanf must read ten chars before reaching the newline, will that occur after the loop has cycled ten times? thanks again.

  5. #5
    Registered User
    Join Date
    Oct 2012
    Posts
    33
    So I've entered your suggested changes. The code is

    Code:
    # include <stdio.h>
    
    
    int main (int argc, char *argv[] )
    
    
    {
        int player;
        char at_bat;
        FILE *fp;
    
    
        fp = fopen( argv[1], "r" );\
    
        while ((fscanf(fp, "%d",  &player)) == 1)
        {
        printf("Player number is %d.\n", player);
           while ((fscanf(fp, "%c", &at_bat)) == 1 && at_bat != '\n')
           {
           fscanf(fp, "%c", &at_bat);
           printf("%c", at_bat);
           }
        }
        return(0);
    }
    my results are

    Player number is 12.
    HOWHOHWH
    SHHWHHO
    PHOWHOO

    The txt file is

    12 HOOOWSHHOOHPWWHO
    4 OSOHHHWWOHOHOOO
    7 WPOHOOHWOHHOWOO

    At least the infinite loop has ended, but still no success.

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Perhaps I should have been a bit more clear. The code I provided correctly reads one character at a time, and exits if that character is a new line.

    Your code was broken because it was waiting for fscanf to return a value of '\n'. fscanf does not return the character it read like getchar does. Instead, it returns the number of items converted. You asked for one, because you only gave one format specifier, "%c". But you were comparing the return value of fscanf to '\n'. That character also has a numeric value -- in fact, all character in any computer are just numbers that map to little pictures of a letter, digit, punctuation (called "glyphs"), or special control characters. The numeric value of '\n' depends on what character set you are using, but most people use ASCII or something compatible, like UTF-8, so '\n' has a numeric value of 10. You can look up such information in an ASCII chart: Ascii Table - ASCII character codes and html, octal, hex and decimal chart conversion. Note, the "Dec" column is the numeric value in base 10, and note that the first 32 values are "control characters", many of which don't actually print anything.

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by Kurtanius21 View Post
    So I've entered your suggested changes. The code is

    Code:
    # include <stdio.h>
    
    
    int main (int argc, char *argv[] )
    
    
    {
        int player;
        char at_bat;
        FILE *fp;
    
    
        fp = fopen( argv[1], "r" );\
    
        while ((fscanf(fp, "%d",  &player)) == 1)
        {
        printf("Player number is %d.\n", player);
           while ((fscanf(fp, "%c", &at_bat)) == 1 && at_bat != '\n')
           {
           fscanf(fp, "%c", &at_bat);
           printf("%c", at_bat);
           }
        }
        return(0);
    }
    my results are

    Player number is 12.
    HOWHOHWH
    SHHWHHO
    PHOWHOO

    The txt file is

    12 HOOOWSHHOOHPWWHO
    4 OSOHHHWWOHOHOOO
    7 WPOHOOHWOHHOWOO

    At least the infinite loop has ended, but still no success.
    Salem caught one other issue that I missed, and you didn't include it in your changes. You don't need the fscanf inside the loop. Remove that line above in red. You call fscanf once in the loop condition, which reads a char, then again inside the loop body, which causes you to only process roughly every other character. It is also causing you to miss the newline and thus miss the "player change".

  8. #8
    Registered User
    Join Date
    Oct 2012
    Posts
    33
    Wow, that did it. No wonder I was getting half the records. That clears up a lot. I didn't realize the loop condition also scanned and stored a variable. I thought it was just a check, not an actual variable update. I'll work with what I got for now, thank you for your help anduril and salem!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. For Loop for making a following program
    By asifbest in forum C++ Programming
    Replies: 2
    Last Post: 10-11-2012, 11:43 AM
  2. Need help on making an array in a loop
    By tak3dat in forum C Programming
    Replies: 3
    Last Post: 05-16-2011, 05:07 AM
  3. Replies: 4
    Last Post: 12-29-2010, 11:11 AM
  4. Need alittle help making this loop
    By Daesom in forum C++ Programming
    Replies: 3
    Last Post: 10-31-2006, 01:41 PM
  5. Replies: 2
    Last Post: 01-13-2003, 01:28 PM