1. atoi関数とは何ですか?
int atoi ( const char * str );
機能: 文字列を整数に変換します。
C 文字列 str を解析し、その内容を整数として解釈し、int 値として返されます。
この関数は、まず最初の非空白文字が見つかるまで、できるだけ多くの空白文字を破棄します。次に、この文字から開始して、オプションの最初のプラス記号またはマイナス記号を取得し、その後に可能な限り多くの数字を続けて、それらを数値として解釈します。 例:「-123456」は-123456に変換されます。
文字列には、整数を構成する文字の後に他の文字が含まれる場合がありますが、それらは無視され、関数の動作には影響しません。例: 「123abc456」は 123 に変換されますが、最終出力は整数ですが、これは不正な変換です
str 内の非空白文字の最初のシーケンスが有効な整数でない場合、または str が空であるか空白文字のみが含まれているためにそのようなシーケンスが存在しない場合、変換は実行されません。例: "abc" " abc" "" は不正な変換であり、最終的には整数 0 が出力されます。
弦 | 整数 | 合法性 |
---|---|---|
「123456」 | 123456 | 正当 |
「-123456」 | -123456 | 正当 |
「123abc456」 | 123 | 違法 |
「ABC」 | 0 | 違法 |
「」 | 0 | 違法 |
「2222222222」 | 任意の値 | 違法 |
注: 変換された値が int で表現できる値の範囲外の場合に何が起こるかについての標準仕様はありません。
例:VS2013コンパイル環境で出力される値
二、atoi関数シミュレーション実装
#include <stdio.h>
#include <limits.h>
#include <ctype.h>
//通过枚举设置两种状态,分别代表字符串转换的合法性
enum Status
{
VALID, //合法
INVALID //非法
};
enum Status status = INVALID; //定义全局变量 status 为 INVALID,若转换合法,则将 status 变为 VALID,若非法则不变
int my_atoi(const char* str)
{
if (str == NULL) //字符串为空
{
return 0;
}
if (*str == '\0') //空白字符
{
return 0;
}
while (isspace(*str)) //字符串前面有多余的空格,则一直往后移寻找符号或数字
{
str++;
}
int flag = 1; //flag 标志数字的正负
if (*str == '+')
{
flag = 1;
str++;
}
else if (*str == '-')
{
flag = -1;
str++;
}
long long ret = 0;
while (isdigit(*str))
{
ret = ret * 10 + flag*(*str - '0');
if (ret<INT_MIN || ret>INT_MAX) //判断转换后的数字是否越界
{
return 0;
}
str++;
}
if (*str == '\0') //若字符串遍历完就走这一步,也就意味着该字符串的转换为合法的
{
status = VALID;
return (int)ret;
}
else //非法转换
{
return (int)ret;
}
}
int main()
{
//int ret = my_atoi("-123");
int ret = my_atoi(" -2222222222");
if (status == VALID)
{
printf("合法的转换:%d\n", ret);
}
else
printf("转换不合法!返回值为:%d\n",ret);
return 0;
}
要約する
基本的に、この関数のシミュレーション実装で注意すべき詳細は、上記のコード コメントにあります。
改めて説明する必要があるのは、なぜ stoi 関数の戻り値の int 型ではなく、long long long integer として戻り値を定義する必要があるのかということです。
これは、合計を計算する際に範囲外があった場合、戻り値が int 型として定義されているため、範囲外のある数値は範囲外でない数値に変換されてしまうためです。誤った出力結果や合法性の誤判断につながります。