web-dev-qa-db-ja.com

c関数atoiが失敗したか、それがゼロの文字列であったかどうかはどのようにしてわかりますか?

関数atoi(またはstrtolまたは同様の関数)を使用する場合、整数変換が失敗したか、変換されていたC文字列が0

私がやっていることでは、0は許容値であり、変換されるC文字列には任意の数の0sを含めることができます。また、先頭に空白がある場合もあります。

35
Jared

C++ 11以降の場合:

文字列から整数への変換のgo-to関数は stoi になりました。これはstringを受け取り、intを返します。またはエラー時に例外をスローします。

受け入れられた回答で言及された冗長なistringstreamハックはもう必要ありません。

(それぞれstol/long long/stoll/stof/long double変換用のstod/stold/long/float/doubleもあります。)

10
emlai

適切な関数(Cスタイルの関数の使用を主張している限り)はstrtolであり、変換コードは次のようになります。

const char *number = "10"; /* for example */

char *end;
long value = strtol(number, &end, 10); 
if (end == number || *end != '\0' || errno == ERANGE)
  /* ERROR, abort */;

/* Success */
/* Add whatever range checks you want to have on the value of `value` */

いくつかの備考:

strtolは、実際の数値の前に空白を許可します(つまり、静かにスキップします)。このような先頭の空白をエラーとして処理する場合は、自分でチェックする必要があります。

*end != '\0'のチェックは、数字の後に何もないことを確認します。実際の数字(空白?)の後に他の文字を許可する場合は、このチェックを適宜変更する必要があります。

追伸空の入力シーケンスをキャッチするために、後でend == numberチェックを追加しました。 「すべての空白」および「番号なし」の入力は、*end != '\0'チェックだけでキャッチされます。ただし、事前に空の入力をキャッチすることは理にかなっています。その場合、end == numberチェックは不要になる可能性があります。

45
AnT

これはタグ付けされているため c ++

template< typename T >
inline T convert(const std::string& str)
{
    std::istringstream iss(str);
    T obj;

    iss >> std::ws >> obj >> std::ws;

    if(!iss.eof())
        throw "dammit!";

    return obj; 
}
23
sbi

Strtol()のmanページから:

EndptrがNULLでない場合、strtol()は最初の無効な文字のアドレスを* endptrに格納します。ただし、数字がまったくない場合、strtol()はnptrの元の値を* endptrに格納します。 (したがって、* nptrが'\0'ではなく、** endptrが'\0'である場合、文字列全体が有効でした。)

strtolに代わるものはsscanfですが、少し重いです:

_const char *numStr = "12345";  // input string
int value;
if(sscanf(numStr, "%d", &value) == 1)
    ;  // parsing succeeded, use value
else
    ;  // error
_

ただし、これにより、文字列の先頭の空白(望ましい場合もそうでない場合もあります)が許可され、数値の末尾に何でも続くことができるため、「123abc」が受け入れられ、123が返されます。より厳密に制御したい場合は、strtol()AndreyTが示すように

2
Adam Rosenfield

私がC/C++を実行してからしばらく経ちましたが、(非常に)単純な解決策は、文字列だけに「0」があるかどうかをチェックすることだと思われます。

int value = atoi(string_number.c_str());

if ( !value && string_number != "0" ) {
  // error
} else {
  // great success!
}
1
Justin Johnson