get_double input function (getchar+scanf)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Martin Jørgensen

    get_double input function (getchar+scanf)

    Hi,

    Since I'm a newbie I have some small but quick (probably) stupid
    questions also :-)

    This is my "get_double " function which takes a default argument also of
    type double. The function returns a value of type double so I can write
    something like value = getdouble(0.5); in my program.

    --------------

    double get_double(doub le default)
    {
    double input;
    char ch;

    while (scanf("%lf", &input) != 1) /* if valid input was not entered */
    {
    while ((ch = getchar()) != '\n')
    putchar(ch); /* dispose bad input */
    printf(" is not valid input. Assuming default value: %lf\n", default);
    input = default;
    }
    return input;
    }

    --------------

    The compiler says:

    syntax error : missing ')' before 'default'
    syntax error : missing '{' before 'default'
    syntax error : 'default'
    syntax error : ')'

    It probably thinks I'm trying to cast some value to type double I
    guess....? What is it complaining about?

    It is declared in the beginning as:

    double get_double(doub le); /* get input of type double */


    Med venlig hilsen / Best regards
    Martin Jørgensen

    --
    ---------------------------------------------------------------------------
    Home of Martin Jørgensen - http://www.martinjoergensen.dk
  • Broeisi

    #2
    Re: get_double input function (getchar+scanf)

    Hello,

    default is a keyword in C.
    It's used in the switch statement..

    Try changing that as that;s the only thing I see that can be a problem
    in the code you posted..

    Broeisi

    Martin Jørgensen wrote:
    [color=blue]
    > Hi,
    >
    > Since I'm a newbie I have some small but quick (probably) stupid
    > questions also :-)
    >
    > This is my "get_double " function which takes a default argument also of
    > type double. The function returns a value of type double so I can write
    > something like value = getdouble(0.5); in my program.
    >
    > --------------
    >
    > double get_double(doub le default)
    > {
    > double input;
    > char ch;
    >
    > while (scanf("%lf", &input) != 1) /* if valid input was not entered */
    > {
    > while ((ch = getchar()) != '\n')
    > putchar(ch); /* dispose bad input */
    > printf(" is not valid input. Assuming default value: %lf\n", default);
    > input = default;
    > }
    > return input;
    > }
    >
    > --------------
    >
    > The compiler says:
    >
    > syntax error : missing ')' before 'default'
    > syntax error : missing '{' before 'default'
    > syntax error : 'default'
    > syntax error : ')'
    >
    > It probably thinks I'm trying to cast some value to type double I
    > guess....? What is it complaining about?
    >
    > It is declared in the beginning as:
    >
    > double get_double(doub le); /* get input of type double */
    >
    >
    > Med venlig hilsen / Best regards
    > Martin Jørgensen
    >[/color]

    Comment

    • Eric Sosman

      #3
      Re: get_double input function (getchar+scanf)



      Martin Jørgensen wrote On 02/16/06 13:45,:[color=blue]
      > [...]
      >
      > double get_double(doub le default)
      > [...]
      > The compiler says:
      >
      > syntax error : missing ')' before 'default'[/color]

      `default' is a keyword; you cannot use it as an
      identifier. What you've written is very much like

      double get_double(doub le return)

      --
      Eric.Sosman@sun .com

      Comment

      • Martin Jørgensen

        #4
        Re: get_double input function (getchar+scanf)

        Eric Sosman wrote:
        -snip-
        [color=blue]
        > `default' is a keyword; you cannot use it as an
        > identifier. What you've written is very much like
        >
        > double get_double(doub le return)[/color]

        Ok, thanks Eric.

        Next (small) problem:

        double get_double(doub le defaultvalue)
        {
        double input;

        if (scanf("%lf", &input) != 1 || input == '\n' || input < 0 || input >1
        ) /* if valid input was not entered */
        {
        printf("That is not valid input (0 <= theta <= 1). Assuming default
        value: %lf\n", defaultvalue);
        input = defaultvalue;
        }
        return input;
        }

        If I hit "enter" it doesn't immediately assign defaultvalue to input,
        but keeps waiting for something. I want: If the user hits enter, input =
        defaultvalue; I thought the "\n" did the job, but it doesn't...


        Med venlig hilsen / Best regards
        Martin Jørgensen

        --
        ---------------------------------------------------------------------------
        Home of Martin Jørgensen - http://www.martinjoergensen.dk

        Comment

        • Eric Sosman

          #5
          Re: get_double input function (getchar+scanf)



          Martin Jørgensen wrote On 02/16/06 15:11,:[color=blue]
          > Eric Sosman wrote:
          > -snip-
          >
          > [color=green]
          >> `default' is a keyword; you cannot use it as an
          >>identifier. What you've written is very much like
          >>
          >> double get_double(doub le return)[/color]
          >
          >
          > Ok, thanks Eric.
          >
          > Next (small) problem:
          >
          > double get_double(doub le defaultvalue)
          > {
          > double input;
          >
          > if (scanf("%lf", &input) != 1 || input == '\n' || input < 0 || input >1
          > ) /* if valid input was not entered */
          > {
          > printf("That is not valid input (0 <= theta <= 1). Assuming default
          > value: %lf\n", defaultvalue);
          > input = defaultvalue;
          > }
          > return input;
          > }
          >
          > If I hit "enter" it doesn't immediately assign defaultvalue to input,
          > but keeps waiting for something. I want: If the user hits enter, input =
          > defaultvalue; I thought the "\n" did the job, but it doesn't...[/color]

          The only way input == '\n' can be true is if the
          user entered the number that happens to be equal to the
          numeric code for the newline character -- 10, on many
          systems. In particular, scanf() does not store '\n' (or
          anything else) in the variable when presented with an
          empty line.

          What does it do instead? It keeps on looking for
          something to convert. The "%lf" specifier (like most)
          reads and ignores leading white space until it finds
          something else, and '\n' is white space. You can hit
          ENTER all day long, and scanf() will keep on eating those
          newline characters. It won't return to your code until
          something else is entered.

          scanf() is not a good tool for what you're trying to
          do -- you want to consider the user's input line by line,
          but scanf() is not very sensitive to line boundaries. An
          easy alternative is to read a line with fgets() (*not*
          with gets!()!), and then use sscanf() to extract data
          from the buffered line.

          --
          Eric.Sosman@sun .com

          Comment

          • Fred Kleinschmidt

            #6
            Re: get_double input function (getchar+scanf)


            "Martin Jørgensen" <unoder.spam@sp am.jay.net> wrote in message
            news:0stec3-ih.ln1@news.tdc .dk...[color=blue]
            > Hi,
            >
            > Since I'm a newbie I have some small but quick (probably) stupid questions
            > also :-)
            >
            > This is my "get_double " function which takes a default argument also of
            > type double. The function returns a value of type double so I can write
            > something like value = getdouble(0.5); in my program.
            >
            > --------------
            >
            > double get_double(doub le default)
            > {
            > double input;
            > char ch;
            >
            > while (scanf("%lf", &input) != 1) /* if valid input was not entered */
            > {
            > while ((ch = getchar()) != '\n')
            > putchar(ch); /* dispose bad input */
            > printf(" is not valid input. Assuming default value: %lf\n", default);
            > input = default;
            > }
            > return input;
            > }
            >[/color]

            1) Don't use 'default' as the name of a variable; it is a reserved word.
            2) Don't use scanf, getchar, and putchar.
            Instead, use fgets to read the user's input, then use strtod to convert it
            to a double. You can check strtod's returned pointer to see if there is a
            format error in the user's input.
            --
            Fred L. Kleinschmidt
            Boeing Associate Technical Fellow
            Technical Architect, Software Reuse Project
            [color=blue]
            > --------------[/color]
            <snip>[color=blue]
            > Med venlig hilsen / Best regards
            > Martin Jørgensen
            >
            > --
            > ---------------------------------------------------------------------------
            > Home of Martin Jørgensen - http://www.martinjoergensen.dk[/color]


            Comment

            • Mark McIntyre

              #7
              Re: get_double input function (getchar+scanf)

              On Thu, 16 Feb 2006 21:11:59 +0100, in comp.lang.c , Martin Jørgensen
              <unoder.spam@sp am.jay.net> wrote:
              [color=blue]
              > if (scanf("%lf", &input) != 1 || input == '\n' || input < 0 || input >1[/color]
              [color=blue]
              >If I hit "enter" it doesn't immediately assign defaultvalue to input,
              >but keeps waiting for something.[/color]

              The fix for this is NOT to use scanf. This is only one of the problems
              with the function.
              [color=blue]
              >I want: If the user hits enter, input =
              >defaultvalue ; I thought the "\n" did the job, but it doesn't...[/color]

              \n doesn't match %lf, so scanf ignores it. Use fgets and sscanf.
              Mark McIntyre
              --
              "Debugging is twice as hard as writing the code in the first place.
              Therefore, if you write the code as cleverly as possible, you are,
              by definition, not smart enough to debug it."
              --Brian Kernighan

              ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
              http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
              ----= East and West-Coast Server Farms - Total Privacy via Encryption =----

              Comment

              • Martin Jørgensen

                #8
                Re: get_double input function (getchar+scanf)

                Eric Sosman wrote:
                -snip-
                [color=blue]
                > scanf() is not a good tool for what you're trying to
                > do -- you want to consider the user's input line by line,
                > but scanf() is not very sensitive to line boundaries. An
                > easy alternative is to read a line with fgets() (*not*
                > with gets!()!), and then use sscanf() to extract data
                > from the buffered line.[/color]

                Thanks a lot. Good explanation. I'll dig into that gets()+sscanf() stuff.


                Med venlig hilsen / Best regards
                Martin Jørgensen

                --
                ---------------------------------------------------------------------------
                Home of Martin Jørgensen - http://www.martinjoergensen.dk

                Comment

                • Martin Jørgensen

                  #9
                  Re: get_double input function (getchar+scanf)

                  Mark McIntyre wrote:[color=blue]
                  > On Thu, 16 Feb 2006 21:11:59 +0100, in comp.lang.c , Martin Jørgensen
                  > <unoder.spam@sp am.jay.net> wrote:
                  >
                  >[color=green]
                  >> if (scanf("%lf", &input) != 1 || input == '\n' || input < 0 || input >1[/color]
                  >
                  >[color=green]
                  >>If I hit "enter" it doesn't immediately assign defaultvalue to input,
                  >>but keeps waiting for something.[/color]
                  >
                  >
                  > The fix for this is NOT to use scanf. This is only one of the problems
                  > with the function.[/color]

                  What other problems are there?


                  Med venlig hilsen / Best regards
                  Martin Jørgensen

                  --
                  ---------------------------------------------------------------------------
                  Home of Martin Jørgensen - http://www.martinjoergensen.dk

                  Comment

                  • Michael Mair

                    #10
                    Re: get_double input function (getchar+scanf)

                    Martin Jørgensen schrieb:[color=blue]
                    > Mark McIntyre wrote:[color=green]
                    >> On Thu, 16 Feb 2006 21:11:59 +0100, in comp.lang.c , Martin Jørgensen
                    >> <unoder.spam@sp am.jay.net> wrote:
                    >>[color=darkred]
                    >>> if (scanf("%lf", &input) != 1 || input == '\n' || input < 0 ||
                    >>> input >1[/color]
                    >>[color=darkred]
                    >>> If I hit "enter" it doesn't immediately assign defaultvalue to input,
                    >>> but keeps waiting for something.[/color]
                    >>
                    >> The fix for this is NOT to use scanf. This is only one of the problems
                    >> with the function.[/color]
                    >
                    > What other problems are there?[/color]

                    scanf() does not tell you what kind of errors you have
                    at conversion, whether it left anything in the input line
                    etc.
                    Your function only has stdout to tell the user that something
                    went wrong.

                    Consider the following:

                    ,----
                    #include <stdio.h>
                    #include <stdlib.h>
                    #include <errno.h>
                    #include "ggets/ggets.h"

                    int get_double (double *retval, double *range)
                    {
                    double input;
                    char *buf = NULL, *ctrl;
                    int failure = ggets(&buf);

                    if (failure != 0) {
                    /* You could do further error analysis via failure */
                    failure = failure<0 ? failure : 1;
                    }
                    else {
                    input = strtod(buf, &ctrl);

                    if (ERANGE == errno) {
                    /* fputs("number out of range\n", stderr); */
                    failure = 2;
                    }
                    else if (ctrl == buf) {
                    /* fputs("not valid numeric input\n", stderr); */
                    failure = 3;
                    }
                    #ifdef KNOW_IT_ALL
                    else if (*ctrl != '\0') {
                    /* fputs("some characters have been discarded\n", stderr); */
                    failure = 4;
                    }
                    #endif
                    else {
                    if (range != NULL
                    && (range[0] > input || range[1] < input))
                    {
                    /* fprintf(stderr, "%g not in range [%g, %g]\n",
                    input, range[0], range[1]);
                    */
                    failure = 5;
                    }
                    else
                    *retval = input;
                    }
                    }

                    free(buf);
                    return failure;
                    }

                    int main (void)
                    {
                    double value = 42.0;
                    double range[] = {0.0, 1.0};
                    int retval;

                    do {
                    printf("> "); (void)fflush(st dout);
                    retval = get_double(&val ue, range);
                    printf("(%d) ", retval);
                    if (0 == retval)
                    printf("%g", value);
                    putchar('\n');
                    } while (value != 0.0);

                    return 0;
                    }

                    `----

                    The only unsafe part is that value could be used
                    uninitialised if a non-zero return value of get_double
                    is ignored.
                    ggets is the one "Available at
                    <http://cbfalconer.home .att.net/download/ggets.zip>"
                    as Chuck Falconer puts it.


                    Cheers
                    Michael
                    --
                    E-Mail: Mine is an /at/ gmx /dot/ de address.

                    Comment

                    • Mark McIntyre

                      #11
                      Re: get_double input function (getchar+scanf)

                      On Fri, 17 Feb 2006 20:06:11 +0100, in comp.lang.c , Martin Jørgensen
                      <unoder.spam@sp am.jay.net> wrote:
                      [color=blue]
                      >Eric Sosman wrote:
                      >-snip-
                      >[color=green]
                      >> scanf() is not a good tool for what you're trying to
                      >> do -- you want to consider the user's input line by line,
                      >> but scanf() is not very sensitive to line boundaries. An
                      >> easy alternative is to read a line with fgets() (*not*
                      >> with gets!()!), and then use sscanf() to extract data
                      >> from the buffered line.[/color]
                      >
                      >Thanks a lot. Good explanation. I'll dig into that gets()+sscanf() stuff.[/color]

                      NO - not gets(), you want fgets().
                      NEVER EVER use gets().
                      Mark McIntyre
                      --
                      "Debugging is twice as hard as writing the code in the first place.
                      Therefore, if you write the code as cleverly as possible, you are,
                      by definition, not smart enough to debug it."
                      --Brian Kernighan

                      ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
                      http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
                      ----= East and West-Coast Server Farms - Total Privacy via Encryption =----

                      Comment

                      • Mark McIntyre

                        #12
                        Re: get_double input function (getchar+scanf)

                        On Fri, 17 Feb 2006 20:06:54 +0100, in comp.lang.c , Martin Jørgensen
                        <unoder.spam@sp am.jay.net> wrote:
                        [color=blue]
                        >What other problems are there?[/color]

                        read the FAQ.
                        Mark McIntyre
                        --
                        "Debugging is twice as hard as writing the code in the first place.
                        Therefore, if you write the code as cleverly as possible, you are,
                        by definition, not smart enough to debug it."
                        --Brian Kernighan

                        ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
                        http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
                        ----= East and West-Coast Server Farms - Total Privacy via Encryption =----

                        Comment

                        • Martin Ambuhl

                          #13
                          Re: get_double input function (getchar+scanf)

                          Martin Jørgensen wrote:[color=blue]
                          > Eric Sosman wrote:
                          > -snip-
                          >[color=green]
                          >> scanf() is not a good tool for what you're trying to
                          >> do -- you want to consider the user's input line by line,
                          >> but scanf() is not very sensitive to line boundaries. An
                          >> easy alternative is to read a line with fgets() (*not*
                          >> with gets!()!), and then use sscanf() to extract data
                          >> from the buffered line.[/color]
                          >
                          >
                          > Thanks a lot. Good explanation. I'll dig into that gets()+sscanf() stuff.[/color]

                          Please don't. Read what Eric wrote ("*not* with gets").

                          Comment

                          • Flash Gordon

                            #14
                            Re: get_double input function (getchar+scanf)

                            Martin Jørgensen wrote:[color=blue]
                            > Eric Sosman wrote:
                            > -snip-
                            >[color=green]
                            >> scanf() is not a good tool for what you're trying to
                            >> do -- you want to consider the user's input line by line,
                            >> but scanf() is not very sensitive to line boundaries. An
                            >> easy alternative is to read a line with fgets() (*not*
                            >> with gets!()!), and then use sscanf() to extract data
                            >> from the buffered line.[/color]
                            >
                            > Thanks a lot. Good explanation. I'll dig into that gets()+sscanf() stuff.[/color]

                            No, NOT gets. NEVER gets. Use fgets as Eric recommended.
                            --
                            Flash Gordon
                            Living in interesting times.
                            Web site - http://home.flash-gordon.me.uk/
                            comp.lang.c posting guidlines and intro -

                            Comment

                            • Martin Jørgensen

                              #15
                              Re: get_double input function (getchar+scanf)

                              Mark McIntyre wrote:
                              -snip-
                              [color=blue][color=green]
                              >>Thanks a lot. Good explanation. I'll dig into that gets()+sscanf() stuff.[/color]
                              >
                              >
                              > NO - not gets(), you want fgets().
                              > NEVER EVER use gets().[/color]

                              Ok, got it. Thanks for the corrections too :-)


                              Med venlig hilsen / Best regards
                              Martin Jørgensen

                              --
                              ---------------------------------------------------------------------------
                              Home of Martin Jørgensen - http://www.martinjoergensen.dk

                              Comment

                              Working...