23

このコードで文字列が数値かどうかを確認したい。文字列内のすべての文字が整数であることを確認する必要がありますが、while は常に isDigit = 1 を返します。それがうまくいかない理由がわかりません。

char tmp[16];
scanf("%s", tmp);

int isDigit = 0;
int j=0;
while(j<strlen(tmp) && isDigit == 0){
  if(tmp[j] > 57 && tmp[j] < 48)
    isDigit = 0;
  else
    isDigit = 1;
  j++;
}
4

12 に答える 12

43

ASCII コードのチェックは忘れて、isdigitorを使用してisnumberください (「 」を参照man isnumber)。最初の関数は文字が 0 ~ 9 かどうかをチェックし、2 番目の関数は現在のロケールに応じて他のさまざまな数字も受け入れます。

チェックを行うためのより良い関数があるかもしれません – 重要な教訓は、「数値文字列」の正確な定義は特定のロケールと文字列エンコーディングに依存するため、これは見た目よりも少し複雑であるということです.

于 2013-05-20T07:53:08.573 に答える
3

コードのこの部分では:

if(tmp[j] > 57 && tmp[j] < 48)
  isDigit = 0;
else
  isDigit = 1;

条件ifは常に false になり、isDigit常に に設定され1ます。あなたはおそらく望んでいます:

if(tmp[j] > '9' || tmp[j] < '0')
  isDigit = 0;
else
  isDigit = 1;

しかし。これは次のように簡略化できます。

isDigit = isdigit(tmp[j]);

ただし、ループのロジックは見当違いのようです。

int isDigit = 0;
int j=0;
while(j<strlen(tmp) && isDigit == 0){
  isDigit = isdigit(tmp[j]);
  j++;
}

は定数ではないためtmp、コンパイラが各反復で長さの計算を最適化するかどうかは不明です。

@andlrc がコメントで示唆しているように、代わりに数字をチェックすることができます。これは、終端の NUL がとにかくチェックに失敗するためです。

while (isdigit(tmp[j])) ++j;
于 2013-05-20T07:53:08.607 に答える
2

現在取り組んでいるプロジェクトでも同じことをする必要があります。これが私が物事を解決した方法です:

/* Prompt user for input */
printf("Enter a number: ");

/* Read user input */
char input[255]; //Of course, you can choose a different input size
fgets(input, sizeof(input), stdin);

/* Strip trailing newline */
size_t ln = strlen(input) - 1;
if( input[ln] == '\n' ) input[ln] = '\0';

/* Ensure that input is a number */
for( size_t i = 0; i < ln; i++){
    if( !isdigit(input[i]) ){
        fprintf(stderr, "%c is not a number. Try again.\n", input[i]);
        getInput(); //Assuming this is the name of the function you are using
        return;
    }
}
于 2016-03-11T01:31:56.013 に答える
0

あなたの状態は言うif X is greater than 57 AND smaller than 48X同時に 57 より大きく 48 より小さくすることはできません。

if(tmp[j] > 57 && tmp[j] < 48)

次のようになりますif X is greater than 57 OR smaller than 48

if(tmp[j] > 57 || tmp[j] < 48)
于 2013-05-20T07:53:56.000 に答える
0

次のように、浮動小数点数をサポートするマルセロの回答を拡張できます。

char isnumber(const char *str)
{
     int decpos = -1, pmpos = -1, engpos = strlen(str) - 1, epmpos = strlen(str) - 1;
  for (int i = 0; i < strlen(str); i++)
    /* check if it is integer */
    if (str[i] > 47 && str[i] < 58)
      continue;
    /* check if it is decimal seperator and used once*/
    else if (str[i] == 46 && decpos == -1)
    {
      decpos = i;
      continue;
    }
    /* check if it is +/-, at the begining*/
    else if ((str[i] == 43 || str[i] == 45) && i == 0)
    {
      pmpos = 1;
      continue;
    }
    /* check if it is engineering format e/E, used once, after decimal and before +/-*/
    else if ((str[i] == 69 || str[i] == 101) && engpos == strlen(str) - 1 && i > 0 && i > decpos && i < epmpos)
    {
      engpos = 1;
      continue;
    }
    /* check if it is engineering format +/-, used once, after decimal and after engineering e/E*/
    else if ((str[i] == 43 || str[i] == 45) && epmpos == strlen(str) - 1 && i > 0 && i > decpos && i > engpos)
    {
      epmpos = 1;
      continue;
    }
    else
      return 0;
  return 1;
}
于 2021-12-08T20:38:43.630 に答える