Strings in C, implemented as a char array, are not actually "text" - they are just sequences of 1-byte numbers (the char type). What causes these numbers to be interpreted as text are just the functions of the standard library - atoi, printf, strlen, etc ... all expect a char pointer - a memory address, from which to traverse the byte at that address and at the following addresses, interpreting those bytes as characters, until a byte with value "0" is reached.
To be clear, a "char" element in C is a number, between -128 and +127 - that "fits" into a single byte. The language syntax allows the value of this number to be written numerically, or as a character, between single-quotes (in this case, the element between single quotes must be part of the ASCII table, or using an escape sequence such as' \ n ',' \ xff ', etc ...). Also, if you are working with numeric values of bytes, it is usually worth working with type unsigned char
, which contains numbers between 0 and 255.
In other words:
...
char a = '0';
printf('%d', (int) a);
...
It will print the code of character '0', which is 48. Whilst:
...
char a = '0';
printf('%c', a);
...
will print the character '0', as it stands: the difference is not in the value contained in variable 'a', but in how printf
will use this value - and this usage is defined by string formatting . Using%% cast in the first example is just to ensure that the compiler will put the value of 'a' using the size of the integer (usually 4 bytes) in the stack - otherwise printf's '% d' could consume 4 bytes where there would be only 1 byte - the 'a' passed as (char) and cause a "Stackunderflow" - commonly known as stack overflow.
Then in your code, the biggest problem is you call (int)
, which expects a memory address for a char sequence, which it interprets as text, and you pass instead a single number. In this case, the compiler will issue a warning, but by default, it will generate the code, treating its character, a number between -128 to 127, as a memory address. When attempting to read this "memory address," the code within the atoi function will not be authorized by the operating system, since those addresses are not part of the memory-sensitive data portion of your program, and an access violation occurs, which is reported by the operating system as a "Segmentation Fault".
Finally, responding by looking at your code:
If you simply subtract the character code '0' from each character of the string entered as string, it will have the numeric value of the digit:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char N[100]; // não tem por que usar um valor pequeno aqui (veja texto abaixo) (*)
int i;
scanf("%s",N);
int cont = strlen(N);
for(i=0; i<cont; i++)
{
int valor = N(i) - '0'; // Subtrai o valor do código de '0' (48) do carácter digitado;
if (valor >= 0 && valor > 9)
{
printf("Dígito %d \n", valor);
}
else
{
printf("Caráctere %c \n",N[i]);
}
}
return (0);
}
(*) About 100 instead of 11 for the array: if the user types in a few more characters this causes bufferoverflow and unpredictable results.
In fact, 'scanf' should be avoided as a whole in production code - see: link