Thread: i need a little help here

  1. #1
    Registered User
    Join Date
    Jan 2008
    Posts
    3

    i need a little help here

    ok im having a little problem here
    im trying to make a simple calculator in C, but everytime i run it and press enter for the first value, i get an error and it closes. here is the source code. please tell me if i messed up on something. Im very new to C and a little help would be great.

    Code:
    #include<stdio.h>
    
    int main()
    {
        
        float operation;
        float x;
        float y;
        float answer;
        printf(" Type 1 for addition, 2 for multiplication, 3 for subtraction, or 4 for division\n");
        printf(" Then type the two numbers.\n");
        scanf("%s",operation);
        scanf("%f",x);
        scanf("%f",y);
        if(operation==1)
        {
                              answer=x + y;
                              }
                              else if(operation==2)
                              {
                                   answer=x * y;
                                   }
                                   else if(operation==3)
                                   {
                                        answer=x - y;
                                        }
                                        else 
                                        {
                                                                answer=x / y;
                                                                }
                                                                
                                                                printf(" The answer is %f!\n",answer);
                                                                
                                                                getchar();
                                                                return 0;
                                                                }

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Code:
        scanf("&#37;s",operation);
        scanf("%f",x);
        scanf("%f",y);
    When reading anything but strings, you need to use an & on the variable to make it a pointer.
    Code:
        scanf("%s",operation);
        scanf("%f",&x);
        scanf("%f",&y);
    You don't need anything for strings, because a string is already a pointer -- an array of chars, usually. Nor do you need the &'s when displaying the values, because printf() doesn't need to set the value to anything else.

    But there's more than that going on here. You're using %s to read a float, which you then compare with an int. Oops. Here are the rules:
    • %f for floats.
    • %i or %d for ints.
    • %s for strings. (Remember, don't use an &.)
    • %c for chars.

    So make up your mind which one you want to use, and use it correctly.

    Also, your indentation really needs some work.
    http://cpwiki.sourceforge.net/Indentation
    http://cpwiki.sourceforge.net/User:Elysia/Indentation
    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.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Reading strings with scanf is dangerous. Read this.
    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.

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Eh, but it's not a string, it's actually a float! But wait, it's being compared with an int . . . .

    Don't forget to check for divide-by-zero.

    As a suggestion: read in the operator as a char. That way the user can enter '+' or '/' instead of 1 or 3 or something.
    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.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, the OP is reading into a float. Of course, it could be done either way. Read a float or read a string. I'd avoid the read a string, as you'll have to read that link otherwise.
    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.

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Quote Originally Posted by Elysia View Post
    Yes, the OP is reading into a float. Of course, it could be done either way. Read a float or read a string. I'd avoid the read a string, as you'll have to read that link otherwise.
    Or read a char, as I suggested. A float makes no sense as an operator, and while a string would work, most operators can be represented with a single character . . . +, -, *, /, and so on.

    Another thing: using one getchar() at the end of your program wouldn't work most of the time, as there would usually be at least a newline in the input buffer, left over from the scanf(). (Unless you typed CTRL-Z or something strange.) I suggest you use something like this:
    Code:
    while(getchar() != '\n');
    while(getchar() != '\n');
    Also see:


    What else . . . oh, yes. Printing a space before every line probably looks rather weird when you run the program.

    (@Elysia: you should make that page into a cpwiki article!)
    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.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by dwks View Post
    Another thing: using one getchar() at the end of your program wouldn't work most of the time, as there would usually be at least a newline in the input buffer, left over from the scanf(). (Unless you typed CTRL-Z or something strange.) I suggest you use something like this:
    Or just skip scanf completely and use fgets and not have to worry about the input buffer at all.

    (@Elysia: you should make that page into a cpwiki article!)
    Yeah, I know. Lazyness and such
    Still, I have a draft saved at the computer so I'll see if I can make it into a wiki article.
    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
    Registered User
    Join Date
    Jan 2008
    Posts
    3
    thanks guys, ill keep those in mind

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Quote Originally Posted by Elysia View Post
    Or just skip scanf completely and use fgets and not have to worry about the input buffer at all.
    Indeed -- but I think it's important to master scanf() first. Or at least understand when to use & and when not to, and what &#37;f means. Because if you use fgets(), you may use sscanf() to get a number out of the string anyway -- or strtol(), which would be smart, or atoi(), which would not.

    So many functions, just to get a number. I think scanf() is a good place to start.

    Yeah, I know. Lazyness and such
    Still, I have a draft saved at the computer so I'll see if I can make it into a wiki article.
    You make it sound like you're not at "the computer". Aha! You have a direct connection to your brain . . . .
    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.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by dwks View Post
    Indeed -- but I think it's important to master scanf() first.
    I say bah to scanf. Throw that stupid function into the fire.
    It's typically unsafe since you never specify buffer size and can easily leave crap in the input buffer which there's no single, compact, easy way to clear.
    The idea of input buffers is just stupid IMO.

    Or at least understand when to use & and when not to, and what %f means.
    You're bound to learn what & means since pointers are a must in C. You don't need scanf for that

    So many functions, just to get a number. I think scanf() is a good place to start.
    I believe it's better to use a function such sprintf or perhaps sscanf. They're better than scanf.

    You make it sound like you're not at "the computer". Aha! You have a direct connection to your brain . . . .
    Hmmm, indeed, do I?
    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,057
    I never said that scanf() was better than line-oriented input like fgets()+strtol(). I said that it was easier. And when someone's just learning how to program, do you think this
    Code:
    scanf("%f", &f);
    or this inspires them more?
    Code:
    if(get_number(&f)) {
        perror("Error reading number");
        exit(1);
    }
    
    int get_number(double *num) {
        char buffer[BUFSIZ], *p, c;
    
        do {
            if(!fgets(buffer, sizeof buffer, stdin)) return 1;
            *num = strtod(buffer, &p);
        } while(p == buffer);
        return 0;
    }
    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をこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Well, it's not a question about inspiring or easier, is it? It's about doing the right thing.
    If scanf would just take another argument that specifies buffer size, it would all be swell, but nope, it doesn't, for some reason.
    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
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    It can, you know.
    Code:
    char buffer[10];
    scanf("&#37;9[^\n]", buffer);
    That's direct from your article. And you're the one who wrote it! . . . .

    Or a more general solution:
    Code:
    scanf("%*[^\n]", sizeof buffer, buffer);
    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.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, I mean it can, but what sort of bizzare and newbie-unfriendly syntax is that?
    It's better to just do (if it worked),
    Code:
    scanf("&#37;s", sizeof(buffer), buffer);
    But it doesn't work! So you have to apply petty syntax tricks to make it work.
    And it doesn't solve the input buffer problem either which are the two reasons that makes it so bad in my eyes.
    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.

  15. #15
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    Quote Originally Posted by dwks View Post
    Or a more general solution:
    Code:
    scanf("%*[^\n]", sizeof buffer, buffer);
    That's the ignore thing.
    Code:
    $ cat t.c
    #include <stdio.h>
    
    int main()
    {
            char buf[8]="erlkjf";
            scanf("%*[^\n]", sizeof buf, buf);
            puts(buf);
            return 0;
    }
    $ gcc -Wall -ansi -pedantic t.c
    t.c: In function ‘main’:
    t.c:6: warning: too many arguments for format
    $ ./a.out
    ert
    erlkjf
    $

Popular pages Recent additions subscribe to a feed