1. ホーム
  2. c++

[解決済み] C: strtol endptr は決して NULL ではない、値が整数のみかどうかを確認できない?

2022-03-05 09:07:36

質問

さて、ここで問題です。私は、.NETと思われるデータセットを持っています。

int int int int ....

しかし、1asdas 2 の場合は "asdas" の部分をキャッチできるようにしたいのです。しかし、今のところ、1 2だけだと、endptrがNULLではないので、値が数字だけなのか、数字と文字なのか、チェックできません。以下は私のコードです。

            else if(token != NULL && token2 != NULL && token3 == NULL){
                    //we POSSIBLY encountered row and column values for the matrix
                    //convert the two numbers to longs base 10 number
                    int row = strtol(token, &result, 10);
                    int col = strtol(token2, &result2, 10);
                    printf("Result is %s and result2 is %s\n", result, result2);
                    //check to see if both numbers are valid
                    //this will be true if there were only 2 digits on the line
                    if(!result && !result2){
                            //SUCCESSFULL parsing of row and column
                            printf("SUCCESSFUL PARSING\n");
                    }
            }

ありがとうございました。

解決方法は?

先のコードですでに行が個々の番号に分割されていると仮定すると、必要なチェックは次のようになります。

errno = 0;
long row = strtol(token, &endtoken, 10);
if (*endtoken != '\0')
    fprintf(stderr, "invalid number '%s' (syntax error)\n", token);
else if (endtoken == token)
    fprintf(stderr, "invalid number '' (empty string)\n");
else if (errno)
    fprintf(stderr, "invalid number '%s' (%s)\n", token, strerror(errno));
else
    /* number is valid, proceed */;

strtol を設定することはありません。 endtoken を指すように設定します。 数字でない最初の文字 . その文字がNULである場合 文字列の終端 (スペルが少し違うことに注意)であれば、文字列全体が有効な数字であったことになります。 ただし endtoken == token を与えたことを意味します。 strtol は空の文字列であり、おそらく有効な数字としてカウントされない。 その errno の範囲外の数字をキャッチするために必要な操作です。 long .

ラインバッファを分割するのではなく、ラインバッファから直接数字を取り出すことで、コードを簡略化できるかもしれません:どの行にも正確に2つの数字があると仮定して。

char *p = linebuf;
char *endp;
errno = 0;
long row = strtol(p, &endp, 10);
if (endp == p || !isspace(p) || errno)
  /* error, abandon parsing */;
p = endp;
long col = strtol(p, &endp, 10);
if (endp == p || p != '\0' || errno)
  /* error, abandon parsing */;