関数atoi
(またはstrtol
または同様の関数)を使用する場合、整数変換が失敗したか、変換されていたC文字列が0
?
私がやっていることでは、0
は許容値であり、変換されるC文字列には任意の数の0
sを含めることができます。また、先頭に空白がある場合もあります。
文字列から整数への変換のgo-to関数は stoi
になりました。これはstring
を受け取り、int
を返します。またはエラー時に例外をスローします。
受け入れられた回答で言及された冗長なistringstream
ハックはもう必要ありません。
(それぞれstol
/long long
/stoll
/stof
/long double
変換用のstod
/stold
/long
/float
/double
もあります。)
適切な関数(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
チェックは不要になる可能性があります。
これはタグ付けされているため 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;
}
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が示すように 。
私がC/C++を実行してからしばらく経ちましたが、(非常に)単純な解決策は、文字列だけに「0」があるかどうかをチェックすることだと思われます。
int value = atoi(string_number.c_str());
if ( !value && string_number != "0" ) {
// error
} else {
// great success!
}