Elementary questions from a beginner

Discussion in 'C Programming' started by Sathyaish, Mar 1, 2004.

  1. Sathyaish

    Sathyaish Guest

    Please forgive my nescience. I have worked extensively on Win32 but I
    am only familiar with C and C++. Lately, I have been practicing C from
    K&R. Here 're a few doubts I have written in the comments. I'd be
    grateful if someone could answer them.

    #include <stdio.h>

    void main()
    {

    /*This program reproduces on the screen whatever you write on your
    keyboard. TWICE.
    One time it writes the output by default (out of the program) and the
    other time it writes
    because the program is at work.

    So if yo write to the screen the following it appears as:

    Hello, this is a test program
    Hello, this is a test program

    The repitition occurs at the press of the Enter key.

    This is one thing I don't understand. Why is the output repeated at
    the press of the enter key? Does getchar terminate
    reading at a newline? It doesn't seem so because after the newline it
    is still reading inside the while loop. It does
    not terminate the loop. It only puts char on the output device after
    every newline. Something I should expect from
    getline(). This is my doubt.

    Another doubt I have resolved by heuristic endeavour is the EOF
    character representation on the keyboard is Ctrl+Z.
    Why?

    Another doubt has just creeped up. When I press Ctrl+C, it just
    terminates without warning. When I press Ctrl+Z, it
    asks, "Press any key to continue". Pressing any key thereafter
    terminates the program. Why is that so?

    I've also tried to print EOF. The value, it seems to me from the
    output is -1. K&R says EOF value is big enough to
    distinguish from char type range. As I see, -1 is not really *BIG
    ENOUGH* but an illegal value for a char type because
    normally char type is unsigned. But then I am reminded of the two's
    complement representation of numbers. Does the K&R
    book say it's *BIG ENOUGH* because of the binary representation of -1
    being all 1s, and therefore the largest possible
    value in the range?

    */

    int c;

    while ((c=getchar()) != EOF) putchar(c);
    printf("%d", EOF);


    //To emulate EOF, press Ctrl+Z


    }
     
    Sathyaish, Mar 1, 2004
    #1
    1. Advertising

  2. Sathyaish <> scribbled the following:
    > Please forgive my nescience. I have worked extensively on Win32 but I
    > am only familiar with C and C++. Lately, I have been practicing C from
    > K&R. Here 're a few doubts I have written in the comments. I'd be
    > grateful if someone could answer them.


    > #include <stdio.h>


    > void main()


    Non-standard form of main(). Better would be int main(void).

    > {


    > /*This program reproduces on the screen whatever you write on your
    > keyboard. TWICE.
    > One time it writes the output by default (out of the program) and the
    > other time it writes
    > because the program is at work.


    > So if yo write to the screen the following it appears as:


    > Hello, this is a test program
    > Hello, this is a test program


    > The repitition occurs at the press of the Enter key.


    > This is one thing I don't understand. Why is the output repeated at
    > the press of the enter key?


    It isn't. The first line isn't output, it's echo from your system
    console, which C doesn't even know, or care about. The second line is
    output from your program.

    > Does getchar terminate
    > reading at a newline? It doesn't seem so because after the newline it
    > is still reading inside the while loop. It does
    > not terminate the loop. It only puts char on the output device after
    > every newline. Something I should expect from
    > getline(). This is my doubt.


    Your console (which is an OS concept and not a C one) buffers characters
    until you press Enter. It then sends all of them to your C program,
    which obediently displays them back to stdout, causing the second line
    of text.

    > Another doubt I have resolved by heuristic endeavour is the EOF
    > character representation on the keyboard is Ctrl+Z.
    > Why?


    Because the makers of your OS thought it would be nice. It could be
    any key combination they want.

    > Another doubt has just creeped up. When I press Ctrl+C, it just
    > terminates without warning. When I press Ctrl+Z, it
    > asks, "Press any key to continue". Pressing any key thereafter
    > terminates the program. Why is that so?


    Your program is not causing this. Your compiler environment is. There is
    no code in your program to display "Press any key to continue", so it
    isn't doing it. Your compiler environment is noticing the program's end
    and printing this "Press any key to continue" all on its own. Try
    exiting your compiler and running your program straight from the command
    line.

    > I've also tried to print EOF. The value, it seems to me from the
    > output is -1. K&R says EOF value is big enough to
    > distinguish from char type range. As I see, -1 is not really *BIG
    > ENOUGH* but an illegal value for a char type because
    > normally char type is unsigned. But then I am reminded of the two's
    > complement representation of numbers. Does the K&R
    > book say it's *BIG ENOUGH* because of the binary representation of -1
    > being all 1s, and therefore the largest possible
    > value in the range?


    EOF should be a value normally outside the range of (signed) char.
    The C standard specifies EOF has to be a negative value. Because of
    this, the return value of getchar() is int, not char, and you should
    make note of this in your program.
    The binary representation of -1 is not standardised. It could be all 1s,
    but then it could be something different. So therefore the comment in
    K&R is wrong, or at least confusing. The point is that EOF's value
    must be outside the range of signed char.

    > */


    > int c;


    > while ((c=getchar()) != EOF) putchar(c);
    > printf("%d", EOF);
    >


    > //To emulate EOF, press Ctrl+Z



    > }


    --
    /-- Joona Palaste () ------------- Finland --------\
    \-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
    "'It can be easily shown that' means 'I saw a proof of this once (which I didn't
    understand) which I can no longer remember'."
    - A maths teacher
     
    Joona I Palaste, Mar 1, 2004
    #2
    1. Advertising

  3. "Joona I Palaste" <> wrote in message
    news:c1v3r7$8og$...
    > EOF should be a value normally outside the range of (signed) char.
    > The C standard specifies EOF has to be a negative value.


    That would make it "at least" (read: farther from zero than) -127.
    More if CHAR_BIT > 8.

    As far as I understand the document, all that is required is that
    EOF has the type int and is negative. ITYM unsigned char.
     
    Peter Pichler, Mar 1, 2004
    #3
  4. Peter Pichler <> scribbled the following:
    > "Joona I Palaste" <> wrote in message
    > news:c1v3r7$8og$...
    >> EOF should be a value normally outside the range of (signed) char.
    >> The C standard specifies EOF has to be a negative value.


    > That would make it "at least" (read: farther from zero than) -127.
    > More if CHAR_BIT > 8.


    > As far as I understand the document, all that is required is that
    > EOF has the type int and is negative. ITYM unsigned char.


    You think right. I was thinking "unsigned char" and writing "signed
    char". Call it a brain-to-fingertips communication failure.

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
    "This isn't right. This isn't even wrong."
    - Wolfgang Pauli
     
    Joona I Palaste, Mar 1, 2004
    #4
  5. Sathyaish

    John Cochran Guest

    In article <c1v3r7$8og$>,
    Joona I Palaste <> wrote:
    SNIP...

    >
    >EOF should be a value normally outside the range of (signed) char.
    >The C standard specifies EOF has to be a negative value. Because of
    >this, the return value of getchar() is int, not char, and you should
    >make note of this in your program.
    >The binary representation of -1 is not standardised. It could be all 1s,
    >but then it could be something different. So therefore the comment in
    >K&R is wrong, or at least confusing. The point is that EOF's value
    >must be outside the range of signed char.


    Wrong.
    EOF simply needs to be a negative number. The functions fgetc(), getc(), etc.
    return an unsigned char cast to an integer. Therefore they return only
    positive numbers even if the type of char is signed. The most common value
    for EOF is -1 and there is no requirement for EOF to not match a legal value
    for a signed character.
     
    John Cochran, Mar 1, 2004
    #5
  6. John Cochran wrote:
    > In article <c1v3r7$8og$>,
    > Joona I Palaste <> wrote:
    >>EOF should be a value normally outside the range of (signed) char.
    >>The C standard specifies EOF has to be a negative value. Because of
    >>this, the return value of getchar() is int, not char, and you should
    >>make note of this in your program.
    >>The binary representation of -1 is not standardised. It could be all 1s,
    >>but then it could be something different. So therefore the comment in
    >>K&R is wrong, or at least confusing. The point is that EOF's value
    >>must be outside the range of signed char.

    >
    > Wrong.
    > EOF simply needs to be a negative number. The functions fgetc(), getc(), etc.
    > return an unsigned char cast to an integer. Therefore they return only
    > positive numbers even if the type of char is signed.


    The fgetc() function returns an unsigned char converted to an int (not
    "integer"). If sizeof(int) is 1 then some characters will result in
    negative return values from fgetc(). In such cases fgetc() may return
    a value that compares equal to EOF even though end-of-file has not
    been reached and no read error has occurred:

    In other words, the following code will not behave correctly on
    implementations where sizeof(int) is 1:

    int c;
    while ((c = fgetc(fp)) != EOF) {
    /* process c */
    }

    The robust way is to use the feof() and ferror() functions:

    int c;
    while (c = fgetc(fp), !feof(fp) && !ferror(fp)) {
    /* process c */
    }

    Jeremy.
     
    Jeremy Yallop, Mar 1, 2004
    #6
  7. Sathyaish

    Sathyaish Guest

    Thank you so much, friends. You have spent your precious time
    understanding my problem and helping me out with answers.

    Since there are so many questions in this post, I would request some
    more of your time, in which I shall be reading each of the answers in
    the light of my questions to better understand the concepts. I still
    feel there's something missing that I could not communciate well
    enough. So it would take me a few days' time to come back with more
    questions on this thread.

    Thank you so much for your time, friends.

    Warm Regards,
    Sathyaish Chakravarthy



    Jeremy Yallop <> wrote in message news:<>...
    > John Cochran wrote:
    > > In article <c1v3r7$8og$>,
    > > Joona I Palaste <> wrote:
    > >>EOF should be a value normally outside the range of (signed) char.
    > >>The C standard specifies EOF has to be a negative value. Because of
    > >>this, the return value of getchar() is int, not char, and you should
    > >>make note of this in your program.
    > >>The binary representation of -1 is not standardised. It could be all 1s,
    > >>but then it could be something different. So therefore the comment in
    > >>K&R is wrong, or at least confusing. The point is that EOF's value
    > >>must be outside the range of signed char.

    > >
    > > Wrong.
    > > EOF simply needs to be a negative number. The functions fgetc(), getc(), etc.
    > > return an unsigned char cast to an integer. Therefore they return only
    > > positive numbers even if the type of char is signed.

    >
    > The fgetc() function returns an unsigned char converted to an int (not
    > "integer"). If sizeof(int) is 1 then some characters will result in
    > negative return values from fgetc(). In such cases fgetc() may return
    > a value that compares equal to EOF even though end-of-file has not
    > been reached and no read error has occurred:
    >
    > In other words, the following code will not behave correctly on
    > implementations where sizeof(int) is 1:
    >
    > int c;
    > while ((c = fgetc(fp)) != EOF) {
    > /* process c */
    > }
    >
    > The robust way is to use the feof() and ferror() functions:
    >
    > int c;
    > while (c = fgetc(fp), !feof(fp) && !ferror(fp)) {
    > /* process c */
    > }
    >
    > Jeremy.
     
    Sathyaish, Mar 2, 2004
    #7
  8. Sathyaish

    Dan Pop Guest

    In <> Jeremy Yallop <> writes:

    >In other words, the following code will not behave correctly on
    >implementations where sizeof(int) is 1:
    >
    > int c;
    > while ((c = fgetc(fp)) != EOF) {
    > /* process c */
    > }
    >
    >The robust way is to use the feof() and ferror() functions:
    >
    > int c;
    > while (c = fgetc(fp), !feof(fp) && !ferror(fp)) {
    > /* process c */
    > }


    OTOH, sizeof(int) == 1 would render <ctype.h> unimplementable:

    1 The header <ctype.h> declares several functions useful for
    classifying and mapping characters. In all cases the argument
    is an int, the value of which shall be representable as an
    unsigned char or shall equal the value of the macro EOF. If the
    argument has any other value, the behavior is undefined.

    On such an implementation, there are unsigned char values that cannot
    be represented by an int. Passing such a value to a <ctype.h> function
    would either generate the wrong answer (if the result of converting the
    unsigned char value to int was non-negative) or invoke undefined
    behaviour (if the result of the conversion was negative).

    So, unless you're coding for freestanding implementations (which need
    not provide <ctype.h> at all or as specified by the C standard), you can
    safely assume that sizeof(int) > 1 and use the first loop above, as
    taught by virtually any C book.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Mar 2, 2004
    #8
  9. Sathyaish

    pete Guest

    Dan Pop wrote:
    >
    > In <> Jeremy Yallop <> writes:
    >
    > >In other words, the following code will not behave correctly on
    > >implementations where sizeof(int) is 1:
    > >
    > > int c;
    > > while ((c = fgetc(fp)) != EOF) {
    > > /* process c */
    > > }
    > >
    > >The robust way is to use the feof() and ferror() functions:
    > >
    > > int c;
    > > while (c = fgetc(fp), !feof(fp) && !ferror(fp)) {
    > > /* process c */
    > > }

    >
    > OTOH, sizeof(int) == 1 would render <ctype.h> unimplementable:
    >
    > 1 The header <ctype.h> declares several functions useful for
    > classifying and mapping characters. In all cases the argument
    > is an int, the value of which shall be representable as an
    > unsigned char or shall equal the value of the macro EOF. If the
    > argument has any other value, the behavior is undefined.
    >
    > On such an implementation, there are unsigned char values that cannot
    > be represented by an int.
    > Passing such a value to a <ctype.h> function
    > would either generate the wrong answer
    > (if the result of converting the
    > unsigned char value to int was non-negative) or invoke undefined
    > behaviour (if the result of the conversion was negative).


    I don't see why that is a problem.
    The description of the ctype functions,
    implies that there may any number of int values for arguments,
    which cause undefined behavior in a ctype function.

    isdigit(EOF == -1 ? -2 : -1)

    The description of the ctype functions does not say that
    they should be able to take any unsigned char value as an argument,
    only that the int argument value should also be representable as
    an unsigned char.

    --
    pete
     
    pete, Mar 2, 2004
    #9
  10. Sathyaish

    Dan Pop Guest

    In <> pete <> writes:

    >Dan Pop wrote:
    >>
    >> In <> Jeremy Yallop <> writes:
    >>
    >> >In other words, the following code will not behave correctly on
    >> >implementations where sizeof(int) is 1:
    >> >
    >> > int c;
    >> > while ((c = fgetc(fp)) != EOF) {
    >> > /* process c */
    >> > }
    >> >
    >> >The robust way is to use the feof() and ferror() functions:
    >> >
    >> > int c;
    >> > while (c = fgetc(fp), !feof(fp) && !ferror(fp)) {
    >> > /* process c */
    >> > }

    >>
    >> OTOH, sizeof(int) == 1 would render <ctype.h> unimplementable:
    >>
    >> 1 The header <ctype.h> declares several functions useful for

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    >> classifying and mapping characters. In all cases the argument

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    >> is an int, the value of which shall be representable as an
    >> unsigned char or shall equal the value of the macro EOF. If the
    >> argument has any other value, the behavior is undefined.
    >>
    >> On such an implementation, there are unsigned char values that cannot
    >> be represented by an int.
    >> Passing such a value to a <ctype.h> function
    >> would either generate the wrong answer
    >> (if the result of converting the
    >> unsigned char value to int was non-negative) or invoke undefined
    >> behaviour (if the result of the conversion was negative).

    >
    >I don't see why that is a problem.
    >The description of the ctype functions,
    >implies that there may any number of int values for arguments,
    >which cause undefined behavior in a ctype function.


    OTOH, the underlined text above suggests that, if I have a valid character
    value, I can use these functions. If 'a' > INT_MAX, isalpha('a')
    invokes undefined behaviour.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Mar 3, 2004
    #10
  11. Sathyaish

    pete Guest

    Dan Pop wrote:
    >
    > In <> pete <> writes:
    >
    > >Dan Pop wrote:
    > >>
    > >> In <> Jeremy Yallop <> writes:
    > >>
    > >> >In other words, the following code will not behave correctly on
    > >> >implementations where sizeof(int) is 1:
    > >> >
    > >> > int c;
    > >> > while ((c = fgetc(fp)) != EOF) {
    > >> > /* process c */
    > >> > }
    > >> >
    > >> >The robust way is to use the feof() and ferror() functions:
    > >> >
    > >> > int c;
    > >> > while (c = fgetc(fp), !feof(fp) && !ferror(fp)) {
    > >> > /* process c */
    > >> > }
    > >>
    > >> OTOH, sizeof(int) == 1 would render <ctype.h> unimplementable:
    > >>
    > >> 1 The header <ctype.h> declares several functions useful for

    > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    > >> classifying and mapping characters. In all cases the argument

    > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    > >> is an int, the value of which shall be representable as an
    > >> unsigned char or shall equal the value of the macro EOF. If the
    > >> argument has any other value, the behavior is undefined.
    > >>
    > >> On such an implementation, there are unsigned char values that cannot
    > >> be represented by an int.
    > >> Passing such a value to a <ctype.h> function
    > >> would either generate the wrong answer
    > >> (if the result of converting the
    > >> unsigned char value to int was non-negative) or invoke undefined
    > >> behaviour (if the result of the conversion was negative).

    > >
    > >I don't see why that is a problem.
    > >The description of the ctype functions,
    > >implies that there may any number of int values for arguments,
    > >which cause undefined behavior in a ctype function.

    >
    > OTOH, the underlined text above suggests that,
    > if I have a valid character
    > value, I can use these functions. If 'a' > INT_MAX, isalpha('a')
    > invokes undefined behaviour.


    'a' is a constant of type int.
    'a' can't excede INT_MAX.

    I think that the implication of
    "... if I have a valid character value, I can use these functions."
    is that 'a' is also less than UCHAR_MAX.

    --
    pete
     
    pete, Mar 3, 2004
    #11
  12. Sathyaish

    Ravi Uday Guest

    [snip]

    > In other words, the following code will not behave correctly on
    > implementations where sizeof(int) is 1:
    >
    > int c;
    > while ((c = fgetc(fp)) != EOF) {
    > /* process c */
    > }
    >
    > The robust way is to use the feof() and ferror() functions:
    >
    > int c;
    > while (c = fgetc(fp), !feof(fp) && !ferror(fp)) {
    > /* process c */
    > }


    I just interchanged the order to know the evaluation. Results are not same ??
    Can someone explain to me.

    while ( c1 = (!feof(fp) && !ferror(fp)), fgetc(fp) ){ /* Infinite loop !! */
    /* process c */
    }

    - Ravi


    >
    > Jeremy.
     
    Ravi Uday, Mar 4, 2004
    #12
  13. Sathyaish

    Richard Bos Guest

    (Ravi Uday) wrote:

    > > The robust way is to use the feof() and ferror() functions:
    > >
    > > int c;
    > > while (c = fgetc(fp), !feof(fp) && !ferror(fp)) {
    > > /* process c */
    > > }

    >
    > I just interchanged the order to know the evaluation. Results are not same ??
    > Can someone explain to me.
    >
    > while ( c1 = (!feof(fp) && !ferror(fp)), fgetc(fp) ){ /* Infinite loop !! */
    > /* process c */
    > }


    No wonder. This loop is equivalent to

    c1 = !feof(fp) && !ferror(fp);
    while (fgetc(fp) ){
    /* process c */
    c1 = !feof(fp) && !ferror(fp);
    }

    and since fgetc() rarely if ever returns a zero value for text files,
    this is a semi-infinite loop unless you feed it some binary data.

    Richard
     
    Richard Bos, Mar 4, 2004
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Last Timer

    Elementary question on const

    Last Timer, Jan 30, 2005, in forum: C++
    Replies:
    5
    Views:
    377
    Mike Wahler
    Jan 30, 2005
  2. Lionel B
    Replies:
    5
    Views:
    467
    Gianni Mariani
    Mar 3, 2005
  3. Merrill & Michele

    elementary construction

    Merrill & Michele, Sep 22, 2004, in forum: C Programming
    Replies:
    18
    Views:
    542
    Mark McIntyre
    Sep 27, 2004
  4. Merrill & Michele

    elementary construction +1

    Merrill & Michele, Sep 24, 2004, in forum: C Programming
    Replies:
    29
    Views:
    754
    Mark McIntyre
    Oct 18, 2004
  5. Ted

    Elementary security questions

    Ted, Feb 7, 2007, in forum: ASP .Net Security
    Replies:
    0
    Views:
    151
Loading...

Share This Page