質問

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

man ページによると、引数が一致するだけでなく、同じ効果があるようです。

long atol(const char *nptr);

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

一般的なケースとして、 base 引数 (10 進数しかありません)、どの関数を使用すればよいですか?

役に立ちましたか?

解決

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 非常にシンプルで制御されたケースにのみ適している場合があります。

他のヒント

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

この意味は atol 関数 (他のすべての関数と同様) ato.. 関数) は、本格的な実用的な目的にはほとんど役に立ちません。これは設計ミスであり、その場所は C の歴史の廃品置き場にありました。からの関数を使用する必要があります strto... 変換を実行するグ​​ループ。それらは、とりわけ、の機能に固有の問題を修正するために導入されました。 ato... グループ。

による 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.

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

C99標準の状態について ato* 関数:

エラーの動作を除いて、それらは

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

atol(str) に相当します

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

エンドポインターが必要な場合(読むべき文字が増えているかどうかを確認するか、実際に読んでいるかどうかを確認するため)、または10以外のベースを使用する場合は、strtolを使用します。

メモリが役立つ場合、 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" */

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;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top