1

I was trying to print the Ascii chars and I found that using char c = NUM; printf("%c", c); would work for some numbers (tried the Ascii numbers for some of the alphabet) but some would cause a run time error, why is that?

#include <stdio.h>

int main(void) {
    for(int i = 0; i < 128; i++){
        printf("%c", i); // WORKS FINE
    }

    for(char c = '!'; c < '~'; c++){
        printf("%c", c); //WORKS FINE
    }

    #if 0
    for(char d = 0; d < 128; d++){
        printf("%c", d); //IF REMOVED #if 0 --> RUNTIME ERROR
    }
    #endif

    // HOWEVER
    char e = 105;
    printf("%c", e); //OK
    return 0;
}

So, why is the last part working while the third for loop is not?

EDIT

After seeing the answers below I understand that my loop was ill conditioned and I should have stopped it at 127 and not 128. However, when I tried this change - it gave no output at all:

for(unsigned char c = 0; c < 255; c++){
    printf("%c", c);
}

AND

for(char c = -128; c < 127; c++){
    printf("%c", c);
}
Community
  • 1
  • 1
CIsForCookies
  • 12,097
  • 11
  • 59
  • 124

3 Answers3

5

Compiling with warnings will always help:

char.c:9:2: warning: comparison is always true due to limited range of data type [-Wtype-limits]
  for(char d = 0; d < 128; d++){
  ^

The largest value that a signed character can hold is 127. Therefor the loop will never end and will keep cycling forever between -128 and 127.

EDIT:

But as @SilasAbrusco mentions: the behaviour is actually undefined once d is increased past 127, see: Is signed integer overflow still undefined behavior in C++?

Community
  • 1
  • 1
marcolz
  • 2,880
  • 2
  • 23
  • 28
  • Oh, I used Ideone... no warnings :( – CIsForCookies Jan 04 '16 at 16:52
  • +1 clang says the same: `warning: comparison of constant 128 with expression of type 'char' is always true` – ForceBru Jan 04 '16 at 16:52
  • However, I tried this for(char d = -128; d < 127; d++){printf("%c", d); } and it gave me no output – CIsForCookies Jan 04 '16 at 16:54
  • If you are using plain 7-bit ascii, the first 32 characters will not be "printable". You should look up what your system does with those. If you start your loop at 32 (space) and end it at 126, you should be fine: http://www.asciitable.com/ – marcolz Jan 04 '16 at 17:03
2

char is obviously a signed type on your system. And that means the largest value is +127.

So your for loop never terminates. Actually you have undefined behaviour since you will be overflowing the signed char type.

On platforms where char is unsigned, your for loop would work. But it wouldn't be portable.

Also, printf using a char below 32 will do strange things on your terminal since they are control characters. For example 7 might cause a beep.

for(unsigned char c = 32; c <= 126; c++){
    printf("%c", c);
}

will certainly print correctly.

0

you have a problem with char variables because it is signed and you have used the bit sign to display char so when you have 11111111 in your case is -127 not a 128 so d is lower than 128 so the for loop continue d++= -126, ...etc, so for is endless loop:

for(unsigned char d = 0; d < 128; d++){
    printf("%c", d); //IF REMOVED #if 0 --> RUNTIME ERROR
}
developer
  • 4,744
  • 7
  • 40
  • 55