Thread: Need help reading next line from input file

  1. #1
    Registered User
    Join Date
    Sep 2013
    Posts
    20

    Question Need help reading next line from input file

    Hello there, I am fairly new to programming, but i understand the basics (sort of)... I am working on a calculator for my class, and i have run into a speedbump of sorts. I cannot get the program to read from the next line of the input file. it keeps repeating the first line and repeating it over and over and over.... can someone point me in the right direction on where I have made an error and how I can overcome this obstacle. Thank you in advance.

    My code is below:

    Code:
    // PA
    #include <stdio.h>
    #include <stdlib.h>
    #define FILENAME "CommandsProj1.dat"
    
    
    int main(void)
    {
        float i, j;
        char H, Q, op;
        FILE* cmd;
        fopen("CommandsProj1.dat", "r");
            if((cmd = fopen("CommandsProj1.dat", "r")
                )==NULL)
            {
                printf("File could not be opened");
            }
            else
            {
                fscanf(cmd, "%c %f %f", &op, &i, &j);
                while (1)
                {
                    switch (op)
                    {
                        case ('+'):
                            printf("%f + %f = %f \n)", i, j, i + j);
                            if ( feof(cmd) )
                            break;
                        case ('-'):
                            printf("%f - %f = %f \n)", i, j, i - j);
                            if ( feof(cmd) )
                            break;
                        case ('*'):
                            printf("%f * %f = %f \n)", i, j, i * j);
                            if ( feof(cmd) )
                            break;
                        case ('/'):
                            printf("%f / %f = %f \n)", i, j, i / j);
                            if ( feof(cmd) )
                            break;
                        case ('H'):
                            printf("Help Menu Coming soon\n");
                            if ( feof(cmd) )
                            break;
                        case ('Q'):
                            printf("Goodbye");
                            if ( feof(cmd) )
                            break;
                    }
                }
    
    
            }
        fclose(cmd);
    
    
    return(0);
    }
    The data from the text file is below:

    DA
    H
    + 3 5
    - 5 3
    * 10 7
    / 90 10
    H
    * 8 10
    + 2 8
    - 2 8
    / 7 2
    Q

  2. #2
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    You read only the first line because you read only the first line. Call fscanf within your loop.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  3. #3
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    How to use a loop function with user input in C? - Stack Overflow
    Checking for EOF in 6 places can't be the best way, right?

    Also, some indenting might reveal some bugs:
    Code:
    case ('*'):
        printf("%f * %f = %f \n)", i, j, i * j);
        if ( feof(cmd) )
            break; /* break happens only if ... */
    case ('/'):
        printf("%f / %f = %f \n)", i, j, i / j);
        if ( feof(cmd) )
            break;
    Cases "fall through" each other unless you break; in this case the break refers to the switch, not the loop. You both forgot to break from your cases and mistakenly thought you could exit the loop from within the switch. You'll need something else for that. And why copy the op in your printf format strings when you already have op?

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    /* Removed unused macro */
     
    int main(void)
    {
        float i, j;
        char op; /* H and Q are not used */
    
        /* Might as well initialize rather than assign */
        FILE* cmd = fopen("CommandsProj1.dat", "r");
        
        if (cmd == NULL)
        {
            printf("File could not be opened");
            return EXIT_FAILURE; /* Something other than zero */
        }
        
        /* Better to keep success in same scope as call, so no 'else' here. */
    
        /* fscanf returns EOF if it tries to read but
         * isn't able to get any data. So you can put your reading in
         * the loop condition, and when you get to the
         * one-after-last-line, this will be false and 
         * your loop will be done. 
         */
        while (EOF != fscanf(cmd, "%c %f %f", &op, &i, &j))
        {
            float result; 
    
            switch (op)
            {
                case '+': /* No need for parentheses around the case expressions */
                    result = i + j;
                    break; /* Breaks from the switch */
                case '-':
                    result = i - j;
                    break;
                case '*':
                    result = i * j;
                    break;
                case '/':
                    result = i / j;
                    break;
                case 'h': /* why not allow lower case too? */
                case 'H':
                    printf("Help Menu Coming soon\n");
                    continue; /* Continues the loop */
                case 'q':
                case 'Q':
                    printf("Goodbye");
                    goto cleanupArea; 
                    /* goto could be avoided using functions
                       or a "quitting" flag, if you wish */
                default:
                    continue; /* So we skip the printf */
            }
    
            /* reused 'op' here, and removed the ')' */
            printf("%f %c %f = %f \n", i, op, j, result); 
        }
    
    cleanupArea:
        fclose(cmd); 
        return EXIT_SUCCESS; /* The official zero */
    }
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by CodeMonkey View Post
    Code:
    while (EOF != fscanf(cmd, "%c %f %f", &op, &i, &j))
    This isn't a particularly good idea. EOF isn't the only way that fscanf() reports a problem reading. In the example here, if the file contains bad data, the result will be confusing output (at best).

    Mixing continue, break, and goto statements in a switch is really poor form too, unless your goal is to write unnecessarily cryptic code. Note how you have needed to use comments to clarify your intent.


    And (for the OP) naming float variables i and j is awful, since i and j are often used to name integers used for counters. Better to use descriptive names. The compiler doesn't care. People trying to understand your code - including yourself in future - will benefit from descriptive variable names.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Registered User
    Join Date
    Sep 2013
    Posts
    20

    Works fine except....

    [QUOTE=CodeMonkey;1204886]How to use a loop function with user input in C? - Stack Overflow
    Checking for EOF in 6 places can't be the best way, right?[/QUOTE=CodeMonkey;1204886]

    thank you for your help, it has greatly helped me process my program. But i am still running into a few bugs, more specifically, the program does not read or print when the op is "+" or "-". all the other op values ( *, /, H, Q) work fine. Any advice?

    Code:
    // PA
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int main(void)
    {
        float num1, num2;
        char op;
    
    
        FILE* cmd = fopen("CommandsProj1.dat", "r");
    
    
        if (cmd == NULL)
        {
            printf("File could not be opened");
            return EXIT_FAILURE;
        }
    
    
        printf("Welcome to Calculator  * Version 1.0 * \n");
    
    
        while (EOF != fscanf(cmd, "%c %f %f", &op, &num1, &num2))
        {
            float result;
    
    
            switch (op)
            {
                case '+':
                    result = num1 + num2;
                    break;
                case '-':
                    result = num1 - num2;
                    break;
                case '*':
                    result = num1 * num2;
                    break;
                case '/':
                    result = num1 / num2;
                    break;
                case 'H':
                    printf("\nAccepted operations: '+' '-' '*' '/' 'H' 'Q'\n");
                    continue;
                case 'Q':
                    printf("\nThank you for using Calculator  * Version 1.0 *, Goodbye\n");
                    goto cleanupArea;
                default:
                    continue;
            }
            printf("\n%4.2f %c %4.2f = %4.2f \n", num1, op, num2, result);
        }
    
    
    cleanupArea:
        fclose(cmd);
        return EXIT_SUCCESS;
    }
    I have attached a screen shot as well of the result and the text fileNeed help reading next line from input file-calcresults-jpg

  6. #6
    Registered User
    Join Date
    Sep 2013
    Posts
    20
    Quote Originally Posted by grumpy View Post
    This isn't a particularly good idea. EOF isn't the only way that fscanf() reports a problem reading. In the example here, if the file contains bad data, the result will be confusing output (at best).

    Mixing continue, break, and goto statements in a switch is really poor form too, unless your goal is to write unnecessarily cryptic code. Note how you have needed to use comments to clarify your intent.


    And (for the OP) naming float variables i and j is awful, since i and j are often used to name integers used for counters. Better to use descriptive names. The compiler doesn't care. People trying to understand your code - including yourself in future - will benefit from descriptive variable names.
    could it be the EOF thats messing up my output?

  7. #7
    Registered User
    Join Date
    May 2014
    Posts
    12
    I think it's the initial "DA" in the file that's not read in before the loop.

    Also, ideally, the statement "return EXIT_FAILURE" shouldn't be a return statement. The file is not closed properly. Use an "exit" statement instead:

    exit( EXIT_FAILURE);
    Last edited by xrayextra; 06-01-2014 at 10:56 PM.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by xrayextra
    Also, ideally, the statement "return EXIT_FAILURE" shouldn't be a return statement. The file is not closed properly. Use an "exit" statement instead:

    exit( EXIT_FAILURE);
    The return is from the main function so that will make no difference.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Sep 2013
    Posts
    20
    so should I put another case for variable DA? I heard something about flushing input values but am not sure how that works

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by powerfox0
    so should I put another case for variable DA? I heard something about flushing input values but am not sure how that works
    Why is the "DA" in the input in the first place? If it is not required, then it either shouldn't be there (e.g., you should report an input error to the user) or you should read and discard it (e.g., after determining that it isn't valid input).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Sep 2013
    Posts
    20
    is there a way in c to make it so if it reads any variable BESIDES +-*/HQ it goes to the next line again?

  12. #12
    Registered User
    Join Date
    Sep 2013
    Posts
    20
    Help....
    Last edited by powerfox0; 06-01-2014 at 11:44 PM.

  13. #13
    Registered User
    Join Date
    Sep 2013
    Posts
    20
    Code:
    // PA
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int main(void)
    {
        float num1, num2;
        char op;
    
    
        FILE* cmd = fopen("CommandsProj1.dat", "r");
    
    
        if (cmd == NULL)
        {
            printf("File could not be opened");
            return EXIT_FAILURE;
        }
    
    
        printf("Welcome to Calculator (Version 1.0)\n");
    
    
    
    
        while (EOF != fscanf(cmd, "%c %f %f", &op, &num1, &num2))/*  If not End of File, Read data   */
        {
            float result;
    
    
            switch (op)
            {
                case '+':
                    result = num1 + num2;
                    break;
                case '-':
                    result = num1 - num2;
                    break;
                case '*':
                    result = num1 * num2;
                    break;
                case '/':
                    result = num1 / num2;
                    break;
                case 'H':
                    printf("\nHelp menu: accepted operations are '+' '-' '*' '/' 'H' 'Q'\n");
                    continue;
                case 'Q':
                    printf("\nThank you for using Calculator  (Version 1.0)... Goodbye\n");
                    goto cleanupArea;
                case 'DA':
                    continue;
                default:
                    continue;
            }
            printf("\n%4.2f %c %4.2f = %4.2f \n", num1, op, num2, result); /*  Print calculation information.  */
            fflush(stdout);
        }
    
    
    cleanupArea:
    
    
        fclose(cmd); /*  Close file */
        return EXIT_SUCCESS; /*  exit program */
    }
    still can't figure out why case + or - are not printing to screen
    Last edited by powerfox0; 06-01-2014 at 11:29 PM.

  14. #14
    Registered User
    Join Date
    May 2014
    Posts
    12
    Quote Originally Posted by laserlight View Post
    The return is from the main function so that will make no difference.
    Actually it does. Why bother with closing files in the first place if it didn't make a difference?

    the exit() statement closes all open streams before returning control to the system. A simple return doesn't do that.

    EDIT: Nevermind, in this case it won't make a difference because the file wasn't opened to begin with. My bad.

  15. #15
    Registered User
    Join Date
    Sep 2013
    Posts
    20
    The DA was there originally from my teacher..I even changed input file and removed DA. still not giving me anything printed to screen for + or - as op values....
    Last edited by powerfox0; 06-01-2014 at 11:27 PM. Reason: bad format

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 06-07-2012, 02:50 AM
  2. reading input from command line
    By ueg1990 in forum C Programming
    Replies: 4
    Last Post: 01-26-2012, 11:29 PM
  3. reading line by line - input function
    By Lindira-123 in forum C Programming
    Replies: 11
    Last Post: 02-06-2011, 03:34 PM
  4. Replies: 7
    Last Post: 12-13-2010, 02:13 PM
  5. Reading Input from a file, line-by-line
    By Acolyte in forum C Programming
    Replies: 8
    Last Post: 09-30-2007, 01:03 PM

Tags for this Thread