Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

C Programming Language

Puzzle!


Some days ago, I written a mini program like this:
#include <stdio.h>

int main()
{
        char c;
        int n;

        scanf("%d",&n);
        c = getchar();

        return 0;

}

I want to assign n and c specific values,for example,give n and c
values of 5 and 'x' in fact when I input 5 then "enter",the program
is finish.I know when I press "Enter", I assigned '\n' to variable c,
But how can I avoid this?
On 6 2 ,   1 15 , Tak <kakat@gmail.com> wrote:

> Some days ago, I written a mini program like this:
> #include <stdio.h>

> int main()
> {
>         char c;

a mistake: "int c" not "char c"

In article <1180718112.979701.75@i13g2000prf.googlegroups.com>,

Tak  <kakat@gmail.com> wrote:
>Some days ago, I written a mini program like this:
>#include <stdio.h>
>int main()
>{
>    char c;
>    int n;
>    scanf("%d",&n);
>    c = getchar();
>    return 0;
>}
>I want to assign n and c specific values,for example,give n and c
>values of 5 and 'x' in fact when I input 5 then "enter",the program
>is finish.I know when I press "Enter", I assigned '\n' to variable c,
>But how can I avoid this?

while ( (c = getchar()) != EOF && c == '\n' ) { /* empty loop body */ }

Afterwards, c will either be EOF or a character other than \n .
This takes into account that the user might press return several times
before entering the desired character.

But to make this work, you will have to fix the problem the other poster
pointed out: that c should be of type int, not of type char.

--
  Prototypes are supertypes of their clones.           -- maplesoft

(You've already mentioned in a followup that c needs to be an int.)

If you type "5x" and then <enter>, the program will assign 5 to n and
'x' to c.

In a real program, that would be a very unfriendly input format.  If
you must use scanf, you should (a) check its return value, and (b) be
aware of the state the input stream will be in after the call, and act
accordingly; for example, you might want to read and ignore all
characters up to and including a newline (and don't forget to check
for EOF).

A better way to handle input is to read a line at a time using
fgets(), and then analyze the input line once you have it.

--
Keith Thompson (The_Other_Keith) k@mib.org  <http://www.ghoti.net/~kst>
San Diego Supercomputer Center             <*>  <http://users.sdsc.edu/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

Walter Roberson wrote:

... snip ...

> while ( (c = getchar()) != EOF && c == '\n' ) { /* empty loop body */ }

                                      ^^
                {should be !=) :-)

> Afterwards, c will either be EOF or a character other than \n .
> This takes into account that the user might press return several times
> before entering the desired character.

--
 <http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
 <http://www.securityfocus.com/columnists/423>
 <http://www.aaxnet.com/editor/edit043.html>
 <http://kadaitcha.cx/vista/dogsbreakfast/index.html>
                        cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak

<kakat@gmail.com> wrote:
>Some days ago, I written a mini program like this:
>#include <stdio.h>

>    scanf("%d",&n);
>    c = getchar();
>I want to assign n and c specific values,for example,give n and c
>values of 5 and 'x' in fact when I input 5 then "enter",the program
>is finish.I know when I press "Enter", I assigned '\n' to variable c,
>But how can I avoid this?

Don't use scanf.  
--
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

On 6 2 ,   7 26 , Mark McIntyre <markmcint@spamcop.net> wrote:

> On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak

> <kakat@gmail.com> wrote:
> >Some days ago, I written a mini program like this:
> >#include <stdio.h>

> >    scanf("%d",&n);
> >    c = getchar();
> >I want to assign n and c specific values,for example,give n and c
> >values of 5 and 'x' in fact when I input 5 then "enter",the program
> >is finish.I know when I press "Enter", I assigned '\n' to variable c,
> >But how can I avoid this?

> Don't use scanf.  

Then use what?

"Mark McIntyre" <markmcint@spamcop.net> ha scritto nel messaggio
news:hma163d8u8t50m0rqrpcem1lcobheh4l5r@4ax.com...

> On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak
> <kakat@gmail.com> wrote:

>>Some days ago, I written a mini program like this:
>>#include <stdio.h>

>> scanf("%d",&n);
>> c = getchar();

>>I want to assign n and c specific values,for example,give n and c
>>values of 5 and 'x' in fact when I input 5 then "enter",the program
>>is finish.I know when I press "Enter", I assigned '\n' to variable c,
>>But how can I avoid this?

> Don't use scanf.

A little too extreme...
For example:

do {
    int k = scanf("%d", &n);
    switch (k) {
    case EOF:
        /* stdin is finished or there was something wrong. */
        /* React accordingly. */
        break;
    case 0:
        puts("Please enter an integer");
        /* maybe write that to stderr? */
        scanf("%*[^\n]%*c"); /*skip line*/
        continue; /* yes, here break and continue would do the */
                  /* same thing... :-) */
    case 1:
        break;

} while (k < 0);

Or to avoid strange problem if the number input is too large:

#include <limits.h>
#include <errno.h>
do {
    long tmp;
    int k = scanf("%ld", &tmp);
    switch (k) {
    case EOF:
        /* stdin is finished or there was something wrong. */
        /* React accordingly. */
        break;
    case 0:
        puts("Please enter an integer");
        /* maybe write that to stderr? */
        scanf("%*[^\n]%*c"); /*skip line*/
        continue; /* yes, here break and continue would do the */
                  /* same thing... :-) */
    case 1:
        if (tmp < INT_MIN || tmp > INT_MAX) {
            k = tmp < 0 ? INT_MIN : INT_MAX;
            errno = ERANGE;
        } else
            k = tmp;
        break;

Tak wrote, On 02/06/07 04:31:

> On 6 2 ,   7 26 , Mark McIntyre <markmcint@spamcop.net> wrote:
>> On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak

>> <kakat@gmail.com> wrote:
>>> Some days ago, I written a mini program like this:
>>> #include <stdio.h>
>>>    scanf("%d",&n);
>>>    c = getchar();
>>> I want to assign n and c specific values,for example,give n and c
>>> values of 5 and 'x' in fact when I input 5 then "enter",the program
>>> is finish.I know when I press "Enter", I assigned '\n' to variable c,
>>> But how can I avoid this?
>> Don't use scanf.  

> Then use what?

fgets (NOT gets, NEVER gets), getchar, getc, fgetc as appropriate. There
are gotchas on these so you need to read the documentation and search
the groups and the FAQ for further information.
--
Flash Gordon
On 6 2 ,   3 58 , "Army1987" <please.@for.it> wrote:

> "Mark McIntyre" <markmcint@spamcop.net> ha scritto nel messaggionews:hma163d8u8t50m0rqrpcem1lcobheh4l5r@4ax.com...

<snip>
>         scanf("%*[^\n]%*c"); /*skip line*/

I've learnt that statement /scanf("%[^.]", str); /is usually dangerous
in some conditions.
On 6 2 ,   3 39 , Flash Gordon <s@flash-gordon.me.uk> wrote:

> Tak wrote, On 02/06/07 04:31:

> > On 6 2 ,   7 26 , Mark McIntyre <markmcint@spamcop.net> wrote:
> >> On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak
> > Then use what?

> fgets (NOT gets, NEVER gets), getchar, getc, fgetc as appropriate. There
> are gotchas on these so you need to read the documentation and search
> the groups and the FAQ for further information.

I solve problems from ACM-ICPC, so fgets fgetc are not useful.
usually I solved like this :
int main()
{
        int c;
        int n;

        scanf("%d",&n);
        c = getchar();
        c = getchar();

        return 0;

Tak wrote:
> On 6 2 ,   3 58 , "Army1987" <please.@for.it> wrote:
>> "Mark McIntyre" <markmcint@spamcop.net> ha scritto nel
>> messaggionews:hma163d8u8t50m0rqrpcem1lcobheh4l5r@4ax.com...

> <snip>
>>         scanf("%*[^\n]%*c"); /*skip line*/

> I've learnt that statement /scanf("%[^.]", str); /is usually dangerous
> in some conditions.

You've learnt correctly, but that's not what's happening here. The problem
with scanf("%[^.]", str); is that you cannot know in advance whether enough
memory is available to store the string in str. scanf("%*[^\n]%*c");
discards everything it reads, instead of storing it.

"Tak" <kakat@gmail.com> ha scritto nel messaggio
news:1180773802.789151.42330@a26g2000pre.googlegroups.com...

> I solve problems from ACM-ICPC, so fgets fgetc are not useful.
> usually I solved like this :
> int main()
> {
>        int c;
>        int n;

>        scanf("%d",&n);
>        c = getchar();
>        c = getchar();

>        return 0;

> }

This is ok only as long as you know the only character between one number
and the character to be read will be the newline.
BTW, why do you assign c in both calls of getchar()? Isn't
getchar(); c = getchar(); ok?
On 6 2 ,   7 21 , "Army1987" <please.@for.it> wrote:

Yes , it seems cleaner.

I have no idea what ACM-ICPC is.  However fgets, fgetc, getc, etc.
are all available in any standard C compliant system.  That is one
of the purposes of having a standard.

scanf is generally not too useful in interactive work, and should
never be used without checking its return value.

--
 <http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
 <http://www.securityfocus.com/columnists/423>
 <http://www.aaxnet.com/editor/edit043.html>
 <http://kadaitcha.cx/vista/dogsbreakfast/index.html>
                        cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Flash Gordon wrote:
> Tak wrote, On 02/06/07 04:31:

... snip ...

>> Then use what?

> fgets (NOT gets, NEVER gets), getchar, getc, fgetc as appropriate.
> There are gotchas on these so you need to read the documentation
> and search the groups and the FAQ for further information.

Or ggets.  I am pushing this with the idea of getting it
incorporated in the next version of the C standard.  It's free.
See:

   <http://cbfalconer.home.att.net/download/ggets.zip>

--
 <http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
 <http://www.securityfocus.com/columnists/423>
 <http://www.aaxnet.com/editor/edit043.html>
 <http://kadaitcha.cx/vista/dogsbreakfast/index.html>
                        cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

CBFalconer said:

> Flash Gordon wrote:
>> Tak wrote, On 02/06/07 04:31:

> ... snip ...

>>> Then use what?

>> fgets (NOT gets, NEVER gets), getchar, getc, fgetc as appropriate.
>> There are gotchas on these so you need to read the documentation
>> and search the groups and the FAQ for further information.

> Or ggets.  I am pushing this with the idea of getting it
> incorporated in the next version of the C standard.

For so long as it was your pet function, okay, fine - but if you're
going to try to get it into the C Standard, please at the very least
make it take a size_t to specify the maximum buffer allocation you're
prepared to tolerate. As it stands, it's wide open to a Denial of
Memory attack.

For the record, I'm not convinced that it would make a good addition to
the Standard. I'm not even convinced that my own fgetline function
(which is also freely available, and which I obviously prefer to ggets)
would make a good addition.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.

In article <4661A583.FD124@yahoo.com>,

CBFalconer  <cbfalco@maineline.net> wrote:
>I have no idea what ACM-ICPC is.

Association for Computing Machinary, International C Programming Contest?
--
   I was very young in those days, but I was also rather dim.
   -- Christopher Priest

rober@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
> In article <4661A583.FD124@yahoo.com>,
> CBFalconer  <cbfalco@maineline.net> wrote:
>>I have no idea what ACM-ICPC is.

> Association for Computing Machinary, International C Programming Contest?

ACM International Collegiate Programming Contest.
<http://icpc.baylor.edu/icpc/>

I have no idea why this implies that one can't use fgets and fgetc.

--
Keith Thompson (The_Other_Keith) k@mib.org  <http://www.ghoti.net/~kst>
San Diego Supercomputer Center             <*>  <http://users.sdsc.edu/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[snip]

C99 7.19.6.2p10:

    If this object does not have an appropriate type, or if the result
    of the conversion cannot be represented in the object, the
    behavior is undefined.

This applies to fscanf, scanf, and sscanf.  If I run your program and
enter a number that won't fit in type long, I risk nasal demons.

Using any of the *scanf functions with any of the numeric formats,
unless you have complete control over what appears in the input, is
dangerous.  (IMHO, this is a flaw in the standard; this should have
been treated as a matching failure.)

--
Keith Thompson (The_Other_Keith) k@mib.org  <http://www.ghoti.net/~kst>
San Diego Supercomputer Center             <*>  <http://users.sdsc.edu/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

On Sat, 2 Jun 2007 09:58:26 +0200, in comp.lang.c , "Army1987"

okay, fuller version

1)  don't use scanf

2) (experts only) use scanf with the care you would take to handle
live scorpions while holding a sword point-first between your teeth.
--
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

Keith Thompson wrote:

> C99 7.19.6.2p10:

>     If this object does not have an appropriate type, or if the result
>     of the conversion cannot be represented in the object, the
>     behavior is undefined.

> This applies to fscanf, scanf, and sscanf.  If I run your program and
> enter a number that won't fit in type long, I risk nasal demons.

Hmm... I can't say I agree with your interpretation Keith.

How can the %li conversion in scanf overflow a long object?
For %s and %c conversions, it's possible with such an overflow, but I
don't see the same for "numbers".

Of course, I assume there is no type mismatch... between conversion
specifiers and object.

--
Tor <torust [at] online [dot] no>

Very strange advice, the problem at hand, *might* have specified that OP
don't even need to check for input errors.

> 2) (experts only) use scanf with the care you would take to handle
> live scorpions while holding a sword point-first between your teeth.

You can check for errors with scanf() too, it does have a return value
AND you do have the feof() and ferror() functions.

--
Tor <torust [at] online [dot] no>

And the input stream might be via a pipe with guaranteed input data integrity.

Tor Rustad <tor_rus@hotmail.com> writes:
> Keith Thompson wrote:
>> C99 7.19.6.2p10:
>>     If this object does not have an appropriate type, or if the
>> result
>>     of the conversion cannot be represented in the object, the
>>     behavior is undefined.
>> This applies to fscanf, scanf, and sscanf.  If I run your program and
>> enter a number that won't fit in type long, I risk nasal demons.

> Hmm... I can't say I agree with your interpretation Keith.

> How can the %li conversion in scanf overflow a long object?
> For %s and %c conversions, it's possible with such an overflow, but I
> don't see the same for "numbers".

Easily, if the input string represents a number outside the range of
the target type.

> Of course, I assume there is no type mismatch... between conversion
> specifiers and object.

#include <stdio.h>
#include <limits.h>
#include <string.h>
int main(void)
{
#define BIG_ENOUGH 100
    char buf[BIG_ENOUGH];
    long n = 0;
    int result;

    sprintf(buf, "%ld", LONG_MAX);
    memset(buf, '9', strlen(buf));

    printf("LONG_MAX =  %ld\n", LONG_MAX);
    printf("buf      = \"%s\"\n", buf);

    result = sscanf(buf, "%li", &n);
    if (result == 1) {
        printf("n        = %ld\n", n);
    }
    else {
        printf("n        = %ld (may not be meaningful)\n", n);
    }
    printf("sscanf() returned %d\n", result);

    return 0;

}

I get the following results on various systems (all of which are
valid, since the behavior is undefined):

LONG_MAX =  2147483647
buf      = "9999999999"
n        = 2147483647
sscanf() returned 1

LONG_MAX =  9223372036854775807
buf      = "9999999999999999999"
n        = 9223372036854775807
sscanf() returned 1

LONG_MAX =  9223372036854775807
buf      = "9999999999999999999"
n        = -8446744073709551617
sscanf() returned 1

LONG_MAX =  2147483647
buf      = "9999999999"
n        = 1410065407
sscanf() returned 1

LONG_MAX =  9223372036854775807
buf      = "9999999999999999999"
n        = 0 (may not be meaningful)
sscanf() returned -1

--
Keith Thompson (The_Other_Keith) k@mib.org  <http://www.ghoti.net/~kst>
San Diego Supercomputer Center             <*>  <http://users.sdsc.edu/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc