Stavo discutendo del sottile problema che puoi affrontare quando scrivi in C, quindi (per divertimento) ho iniziato a creare un codice antiproiettile in grado di leggere un intero 32 bit dallo stdin.
Ho scritto questo codice:
#include<stdint.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sysexits.h>
void flush_stdin()
{ int c;
while ((c = getchar()) != '\n' && c != EOF);
}
int32_t readInt32()
{
char line[13]; // -2147483648\n#include<stdint.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sysexits.h>
void flush_stdin()
{ int c;
while ((c = getchar()) != '\n' && c != EOF);
}
int32_t readInt32()
{
char line[13]; // -2147483648\n%pre%
int32_t n = 0;
if (fgets(line, sizeof(line), stdin)) {
if (sscanf(line, "%d", &n) == 1) {
if ((line[0] == '-' && n > 0) || (line[0] != '-' && n < 0)) {
fprintf(stderr, "Overflow detected\n");
exit(EX_DATAERR);
}
if (feof(stdin))
flush_stdin();
return n;
}
}
fprintf(stderr, "Error: wrong int32\n");
exit(EX_DATAERR);
}
int main()
{
int32_t r;
r = readInt32();
printf("read %d\n", r);
return 0;
}
int32_t n = 0;
if (fgets(line, sizeof(line), stdin)) {
if (sscanf(line, "%d", &n) == 1) {
if ((line[0] == '-' && n > 0) || (line[0] != '-' && n < 0)) {
fprintf(stderr, "Overflow detected\n");
exit(EX_DATAERR);
}
if (feof(stdin))
flush_stdin();
return n;
}
}
fprintf(stderr, "Error: wrong int32\n");
exit(EX_DATAERR);
}
int main()
{
int32_t r;
r = readInt32();
printf("read %d\n", r);
return 0;
}
È davvero a prova di proiettile come penso? Hai qualche consiglio su questo codice?
Lo svantaggio principale è che tronca il primo 13 byte del tuo input, quindi se fornisci qualcosa come 000000000000001 legge 0.
EDIT:
questo codice funziona come previsto solo se si genera un eseguibile a 64 bit, ma la soluzione fornita da @Colin è migliore ...