c関数atoiが失敗したかどうか、またはゼロの文字列であったかどうかを確認するにはどうすればよいですか?
質問
関数 atoi
(または strtol
または同様の関数)を使用する場合、整数変換が失敗したか、またはCストリングが変換されたのは 0
?
私がしていることでは、 0
は許容値であり、変換されるC文字列には任意の数の 0
が含まれる場合があります。また、先頭に空白がある場合があります。
解決
C ++ 11以降の場合:
文字列から整数への変換のgo-to関数は、 stoi
。これは string
を受け取り、 int
を返すか、エラー時に例外をスローします。
受け入れられた回答に記載されている冗長な istringstream
ハックはもう必要ありません。
( stol
/ stoll
/ stof
/ stod
/ stold
もありますそれぞれ long
/ long long
/ float
/ double
/ long 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'
のチェックにより、数字の後に何もないことを確認します。実際の番号の後に他の文字(空白?)を許可する場合は、このチェックを適宜変更する必要があります。
PS空の入力シーケンスをキャッチするために、後で 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!
}