上記の条件でelseブロックを実行する入力番号はどれですか?もしそうなら
ほとんどのシステムは、最大値と4294967295
を32ビット符号なし整数を使用して、else
ブロックをトリガすることができます入力がありません。
多くの人がコメントしているように、単純な解決策は、可能な場合はより多くのビットを持つ変数を使用することです。しかし、@Brendanによって指摘されているように、それはあなたに他の問題を与えるだけです。
#include <stdio.h>
#include <limits.h>
// Returns 1 if the string can by converted to unsigned int without overflow
// else return 0
int string2unsigned(const char* s, unsigned int* u)
{
unsigned int t = 0;
if (*s > '9' || *s < '0') return 0; // Check for unexpected char
while(*s)
{
if (*s == '\n') break; // Stop if '\n' is found
if (*s > '9' || *s < '0') return 0; // Check for unexpected char
if (t > UINT_MAX/10) return 0; // Check for overflow
t = 10 * t;
if (t > UINT_MAX - (*s - '0')) return 0; // Check for overflow
t = t + (*s - '0');
s++;
}
*u = t;
return 1;
}
int main(void) {
unsigned int u;
char s[100];
if (!fgets(s, 100, stdin)) // Use fgets to read a line
{
printf("Failed to read input\n");
}
else
{
if (string2unsigned(s, &u))
{
printf("OK %u\n", u);
}
else
{
printf("Illegal %s", s);
}
}
return 0;
}
例:
input: 4294967295
output: OK 4294967295
input: 4294967296
output: Illegal 4294967296
Aより堅牢なソリューションではなく、このようなものかもしれないscanf
このような機能を使っての入力を解析するために、独自の機能を書くことです
(私の元のコードのよりよい代替案を提案してくれた@chuxに感謝)
32ビットの整数を指定すると、条件は常にtrueになります。以上です。 – Lundin
前述したように、おそらく64ビットの整数が必要になるでしょう。これらの可用性は、使用しているアーキテクチャによって異なる場合があります。どのアーキテクチャを使用していますか?あるいは、少なくともsizeof(long)とsizeof(long long)のgccレポートについて教えてください。それが '4'ならばあなたは不運です(少なくとも問題はもっと困難になっています)。もしそれらのうちの一つが' 4'より大きければ 'unsigned'の代わりにそれを使うことができます。 – skyking
unsigned intではなくlong long変数を使用します。 'scanf'の書式は"%ld "または"% "になります。PRId64 – LPs