Thread: [BEGINNER] Shouldn't Int store a number?

  1. #1
    Registered User
    Join Date
    Sep 2014
    Posts
    83

    [BEGINNER] Shouldn't Int store a number?

    Int stands for integer I guess.

    Consider the following program:

    Code:
    #include <stdio.h>
    
    int main(void)
    {
        char text[90];
        int i, c, n;
    
        
        // getchar 
        printf("String: ");
        
        n = 0;
        while((c = getchar()) != '\n') //c is an integer
        {
            text[n] = c;
            n++;
        }
        text[n] = '\0';
        printf("Print out the string: %s\n", text);
        
    }
    I first I declared c as a char which makes sense to me (I want to store a character). I wanted to try to declare it as an int, since it can then store EOF. This also works.
    I thought int variables contained numbers and not letters.

    1) Anyone want to clarify this for me?
    2) Shouldn't the int variable store the ASCI number for the particular character?
    3) How does getchar() know that it should jump one step to the right in the while loop? It looks like it should stand at the same character all the time, but it doesn't fortunatuly.
    4) Also the statement c = getchar() is an allocation inside the while loop I guess? Is this recommended? It looks kind of odd to me.

    Thanks a lot!

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by jjohan
    I first I declared c as a char which makes sense to me (I want to store a character). I wanted to try to declare it as an int, since it can then store EOF. This also works.
    I thought int variables contained numbers and not letters.

    1) Anyone want to clarify this for me?
    2) Shouldn't the int variable store the ASCI number for the particular character?
    3) How does getchar() know that it should jump one step to the right in the while loop? It looks like it should stand at the same character all the time, but it doesn't fortunatuly.
    Consider the text of the 1999 edition of the C standard:
    Quote Originally Posted by C99 Clause 7.19.7.6
    Code:
    int getchar(void);
    The getchar function is equivalent to getc with the argument stdin.
    Quote Originally Posted by C99 Clause 7.19.7.5
    Code:
    int getc(FILE *stream);
    The getc function is equivalent to fgetc, except that if it is implemented as a macro, it may evaluate stream more than once, so the argument should never be an expression with side effects.
    Quote Originally Posted by C99 Clause 7.19.7.1
    Code:
    #include <stdio.h>
    int fgetc(FILE *stream);
    If the end-of-file indicator for the input stream pointed to by stream is not set and a next character is present, the fgetc function obtains that character as an unsigned char converted to an int and advances the associated file position indicator for the stream (if defined).

    If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end- of-file indicator for the stream is set and the fgetc function returns EOF. Otherwise, the fgetc function returns the next character from the input stream pointed to by stream. If a read error occurs, the error indicator for the stream is set and the fgetc function returns EOF.
    So, the character that is read is read as an unsigned char, which is then converted to int. Assuming ASCII, if 'A' is read, then you end up with 65 stored in the int. getchar reads the next character from the standard input stream, thus the answer to "how does it know?" is that it is implemented to "know", the details of which are implementation defined.

    Quote Originally Posted by jjohan
    4) Also the statement c = getchar() is an allocation inside the while loop I guess? Is this recommended? It looks kind of odd to me.
    It is a function call within the condition of the loop. If you are careful, it is fine. Problem is, some people carelessly write:
    Code:
    while(c = getchar() != '\n')
    which is equivalent to:
    Code:
    while(c = (getchar() != '\n'))
    and hence wrong.
    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

  3. #3
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Int stands for integer I guess.
    Correct.

    I first I declared c as a char which makes sense to me (I want to store a character). I wanted to try to declare it as an int, since it can then store EOF. This also works.
    Indeed - storing the result in an int is the correct way.

    FAQ > Definition of EOF and how to use it effectively - Cprogramming.com

    In fact, "getchar()" explicitly returns an int.

    Code:
    int getchar ( void );
    I thought int variables contained numbers and not letters.
    C has no notion of "letters". Both int and char are numeric types. Characters, which are usually smaller than ints, are typically used to hold numeric values that represent glyphs to be printed on the screen (e.g. "letters").

    A char that contains 'A' actually contains the hex value 0x41 (assuming ASCII encoding). An int can also contain this value. The difference is the context in which this value is displayed.

    1) Anyone want to clarify this for me?
    Let us know if you have further questions from the information given.

    2) Shouldn't the int variable store the ASCI number for the particular character?
    This is what happens - see above.

    3) How does getchar() know that it should jump one step to the right in the while loop? It looks like it should stand at the same character all the time, but it doesn't fortunatuly.
    I'm not sure of what you mean by "jump one step to the right" and "stand at the same character all the time".

    Consoles are typically line buffered, meaning input is stored on a buffer and not sent to your program until enter is pressed. The first call to "getchar()" will read the first character in the buffer, and "consume" it, so that the next time around "getchar()" will read the next character in the buffer. And so on.

    4) Also the statement c = getchar() is an allocation inside the while loop I guess? Is this recommended? It looks kind of odd to me.
    I'd use the term "assignment" rather than "allocation", but yes, you are correct. This is actually a standard idiom used in the language. I can understand it looks odd, but it's been done since the dawn of C.

    You could do:

    Code:
    while(getchar() != '\n')
    But the problem with this is that the value read by "getchar()" is not stored anywhere, so you can't use that value later in the program if you need it. By assigning it to a variable, the result can be used later on. Assigning it to a variable within the loop condition simplifies the code. This way, you're (1) reading input, (2) storing that input, and (3) checking that input, all at once.

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    1 & 2
    A char is really just a tiny integer -- typically (though not always) 8 bits. Than number can be treated as a character, by mapping the values of a char to a particular symbol, based on a particular character set (e.g. ASCII, EBCDIC). You'll note that ASCII and EBCDIC for example, map different numbers to the letters. 'E' is decimal 69 (0x45) in ASCII and decimal 197 (0xC5) in EBCDIC. Thus, the int variable (and the char variable text[n] where you store it) are really just storing the numerical value of the letter you input. It's the job of getchar and printf to map those numbers to/from the appropriate symbol.

    3
    I'm not sure I understand "jump one step to the right". Please clarify.

    4
    It's not an allocation, it's an assignment. Yes, it might look a bit weird, but it is acceptable, and is used quite often -- you'll get used to it and it will look less weird as you get more familiar with C. However, you're missing the EOF check in there. Try
    Code:
    while ((c = getchar()) != '\n' && c != EOF)
    Otherwise, you run the risk of getting caught in an infinite loop, and storing EOF in text[n] -- though as a char array, EOF will get "coerced" into some char you probably don't want. Also, along the lines of infinite loop, you should add a condition to prevent overflowing the text array:
    Code:
    #define MAX_LEN 90
    char text[MAX_LEN]
    while ((c = getchar()) != '\n' && c != EOF && n < sizeof(text) - 1)
    And: hooray for using constants instead of magic numbers!

  5. #5
    Registered User
    Join Date
    Sep 2014
    Posts
    83
    Thank you the three of you. It helped me understand this much better.

    Quote Originally Posted by Matticus View Post
    C has no notion of "letters". Both int and char are numeric types. Characters, which are usually smaller than ints, are typically used to hold numeric values that represent glyphs to be printed on the screen (e.g. "letters").

    A char that contains 'A' actually contains the hex value 0x41 (assuming ASCII encoding). An int can also contain this value. The difference is the context in which this value is displayed.
    So the type char only exists because it takes less memory than an int?
    One could then rewrite all programs in c and replace all chars with ints?

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by jjohan
    So the type char only exists because it takes less memory than an int?
    No, it is strongly associated with the notion of a "member of the basic execution character set" and somewhat more loosely associated with the notion of a "byte".

    Quote Originally Posted by jjohan
    One could then rewrite all programs in c and replace all chars with ints?
    No, since the standard C notion of a string is a contiguous sequence of char terminated by a null character, and although 'A' is of type int, "A" is not of type array of 2 int. Furthermore, it is always the case that sizeof(char) == 1.
    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

  7. #7
    Registered User
    Join Date
    Sep 2014
    Posts
    83
    Quote Originally Posted by anduril462 View Post
    3
    I'm not sure I understand "jump one step to the right". Please clarify.
    What I meant was is maybe best explained by an example:
    Suppose the string is "Hello"
    Then at first getchar() reads 'H', then in the loop it "jumps one step to the right" to read in 'e' without me telling getchar() to do so.

    Quote Originally Posted by anduril462 View Post
    And: hooray for using constants instead of magic numbers!
    But constants cannot be used for variables that are of float type right?
    Last edited by jjohan; 09-18-2014 at 12:36 PM.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by jjohan
    Suppoese the string is "Hello"
    Then at first getchar() reads 'H', then in the loop it "jumps one step to the right" to read in 'e' without me telling getchar() to do so.
    The fact that you are calling getchar in a loop means that you did indeed "tell" getchar to do so.

    Quote Originally Posted by jjohan
    But constants cannot be used for variables that are of float type right?
    They can. If you are using a macro constant, then specify the type with the f suffix, e.g., 1.23f.
    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 2014
    Posts
    83
    Quote Originally Posted by laserlight View Post

    No, it is strongly associated with the notion of a "member of the basic execution character set" and somewhat more loosely associated with the notion of a "byte".
    Hm, not sure I understand this.

    Quote Originally Posted by laserlight View Post
    No, since the standard C notion of a string is a contiguous sequence of char terminated by a null character, and although 'A' is of type int, "A" is not of type array of 2 int. Furthermore, it is always the case that sizeof(char) == 1.
    OK, but my char text[] array contains integers I guess since text[n] = c, and c is an integer.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by jjohan
    Hm, not sure I understand this.
    The type char also exists for reasons other than "because it takes less memory than an int". It is not even guaranteed that a char will take less memory than an int.

    Quote Originally Posted by jjohan
    OK, but my char text[] array contains integers I guess since text[n] = c, and c is an integer.
    Yes, since char is an integer type. Consider this program:
    Code:
    #include <stdio.h>
    
    int main(void)
    {
        char name[] = "jjohan";
        printf("%s\n", name);
        return 0;
    }
    Compile and run it. Now, let's rewrite the program to replace char with int:
    Code:
    #include <stdio.h>
    
    int main(void)
    {
        int name[] = "jjohan";
        printf("%s\n", name);
        return 0;
    }
    Compile the program and observe the compile error and warning.
    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 2014
    Posts
    83
    OK, nice example Laserlight.

    The first program works as expected.

    The second program gives compile error:
    tempo.c: In function ‘main’:
    tempo.c:5:5: error: wide character array initialized from non-wide string
    int name[] ="jjohan";
    ^
    tempo.c:6:5: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int *’ [-Wformat=]
    printf("%s\n", name);


    So I guess a char array can store integers, but an int array cannot store characters?
    Last edited by jjohan; 09-18-2014 at 02:07 PM.

  12. #12
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    Possibly you are confusing alphanumeric characters and numeric values,
    and confusing integers (whole numbers) and ints (a C storage type)

    A char type, stores one byte of information. Because one byte is large enough
    to store the code for an alphanumeric character, chars are used to store them.

    (unicode characters need 2 bytes; that doesn't apply here)

    The char byte does not store a letter, for example. It stores a code which represents
    that letter. That code is an integer, ie, it is a whole number. But it is not a C int type.

    Chars and ints both store integer values; the difference is in the size, and also in what
    they typically represent. Chars are typically used to store integer values that represent
    alphanumeric characters. Ints are typically used for larger general purpose integer values.

    An array of type char, char string[10], will contain 10 bytes of storage. That array will
    hold 10 characters, ie, it will hold 10 values which represent the respective 10 characters.

    An array of 10 ints, int string[10], will contain 20 bytes of storage. If you really wanted to,
    you could store characters in that array, by assinging values one array element at a time.
    But you could not use that array as a string with standard library functions. Those functions
    are expecting char arrays, not int arrays.
    The sequential character codes are expected to be one byte apart, not two.

    You could interpret an int array yourself if you wanted, accessing each int array element individually.

    Hope that all makes sense

    -
    Last edited by megafiddle; 09-20-2014 at 10:52 PM.

  13. #13
    Registered User
    Join Date
    Sep 2014
    Posts
    83
    Thanks all. You all clarified this for me.

  14. #14
    Registered User zub's Avatar
    Join Date
    May 2014
    Location
    Russia
    Posts
    104
    You can use more readable variation of same loop:

    Code:
    while( 1 ) {
        c = getchar();
        if( c == EOF || c == '\n' ) { break; }
        text[n] = c;
        ++n;
    }
    
    // By the way, you do not check out of bounds. You can fix this by adding a condition n == 90, but much better to use "for" loop.
    
    for( i = 0; i < 90; ++i ) {
        c = getchar();
        if( c == EOF || c == '\n' ) { break; }
        text[i] = c;
    }
    Our goals are clear, tasks are defined! Let's work, comrades! -- Nikita Khrushchev

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. [beginner] detecting number of UpPeRcAsE letters.
    By Digital Android in forum C Programming
    Replies: 6
    Last Post: 03-20-2014, 09:18 PM
  2. Stuck on how to store the highest prime number
    By Sizz in forum C Programming
    Replies: 7
    Last Post: 02-18-2013, 12:25 PM
  3. how number of two-dimensional array store ?
    By zcrself in forum C Programming
    Replies: 8
    Last Post: 11-28-2009, 12:15 AM
  4. store data from ifstream and store in link list
    By peter_hii in forum C++ Programming
    Replies: 2
    Last Post: 10-26-2006, 08:50 AM
  5. Do you store store one off data arrays in a class?
    By blood.angel in forum C++ Programming
    Replies: 5
    Last Post: 06-24-2002, 12:05 PM