68

atol() と strtol() の違いは何ですか?

彼らのマニュアルページによると、それらは同じ効果と一致する引数を持っているようです:

long atol(const char *nptr);

long int strtol(const char *nptr, char **endptr, int base);

一般的なケースで、引数を使用したくない場合base(10 進数しかない場合)、どの関数を使用すればよいですか?

4

7 に答える 7

98

strtol文字列全体が整数に変換されたかどうかを実際に知ることができるため、柔軟性が向上します。atolは、文字列を数値に変換できない場合 ( のようにatol("help"))、 と区別できない 0 を返しますatol("0")

int main()
{
  int res_help = atol("help");
  int res_zero = atol("0");

  printf("Got from help: %d, from zero: %d\n", res_help, res_zero);
  return 0;
}

出力:

Got from help: 0, from zero: 0

strtol引数を使用してendptr、変換が失敗した場所を指定します。

int main()
{
  char* end;
  int res_help = strtol("help", &end, 10);

  if (!*end)
    printf("Converted successfully\n");
  else
    printf("Conversion error, non-convertible part: %s", end);

  return 0;
}

出力:

Conversion error, non-convertible part: help

したがって、本格的なプログラミングでは、 を使用することを強くお勧めしstrtolます。使い方は少しトリッキーですが、上で説明したように、これには正当な理由があります。

atol非常に単純で制御されたケースにのみ適している場合があります。

于 2010-09-25T05:54:57.990 に答える
22

atol機能は、使用可能なエラー処理機能を提供しないことをstrtol除いて、機能のサブセットです。atol関数の最も顕著な問題ato...は、オーバーフローの場合に未定義の動作が発生することです。注: これは、エラーが発生した場合に有益なフィードバックが得られないというだけではありません。これは未定義の動作です。つまり、通常は回復不能な障害です。

これは、atol関数 (および他のすべてのato..関数) が、実際の実用的な目的にはほとんど役に立たないことを意味します。これは設計ミスであり、その場所は C の歴史のジャンクヤードにあります。strto...変換を実行するには、グループの関数を使用する必要があります。それらは、とりわけ、ato...グループの機能に固有の問題を修正するために導入されました。

于 2010-09-25T05:57:09.117 に答える
19

man ページによると、atoiによって廃止されましたstrtol

IMPLEMENTATION NOTES
The atoi() and atoi_l() functions have been deprecated by strtol() and strtol_l() 
and should not be used in new code.
于 2012-11-08T05:34:54.537 に答える
5

atol(str)と同等です

strtol(str, (char **)NULL, 10);

エンド ポインターが必要な場合 (読み取る文字が他にあるかどうか、または実際に読み取った文字があるかどうかを確認するため)、または 10 以外の基数が必要な場合は、strtol を使用します。それ以外の場合は、atol で問題ありません。

于 2010-09-25T05:55:48.980 に答える
4

新しいコードでは、常にstrtol. エラー処理があり、endptr引数により、文字列のどの部分が使用されたかを確認できます。

C99 標準では、ato*関数について次のように述べられています。

エラー時の動作を除いて、それらは同等です

atoi: (int)strtol(nptr,(char **)NULL, 10)
atol: strtol(nptr,(char **)NULL, 10)
atoll: strtoll(nptr, (char **)NULL, 10)

于 2010-09-25T05:55:42.373 に答える
2

メモリが機能する場合、変換できなかった最初の文字を指すようにstrtol()(オプション) を設定するという追加の利点があります。endptrの場合NULLは無視されます。そうすれば、数字と文字が混在する文字列を処理している場合でも、続行できます。

例えば、

char buf[] = "213982 and the rest";
char *theRest;
long int num = strtol(buf, &theRest, 10);
printf("%ld\n", num);    /* 213982 */
printf("%s\n", theRest); /* " and the rest" */
于 2010-09-25T05:56:08.423 に答える
1

strtol の man ページには、次のように記載されています。

ERRORS
   EINVAL (not in C99) The given base contains an unsupported value.
   ERANGE The resulting value was out of range.
   The implementation may also set errno to EINVAL in case no conversion was performed (no digits seen, and 0 returned).

次のコードは、範囲エラーをチェックします。(Eli のコードを少し変更)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int main()
{
   errno = 0;
   char* end = 0;
   long res = strtol("83459299999999999K997", &end, 10);

   if(errno != 0)
   {
      printf("Conversion error, %s\n", strerror(errno));
   }
   else if (*end)
   {
      printf("Converted partially: %i, non-convertible part: %s\n", res, end);
   }
   else
   {
      printf("Converted successfully: %i\n", res);
   }

   return 0;
}
于 2012-12-05T17:41:13.943 に答える