C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で独自のatoi()関数を実装する方法

C言語およびC++の標準ライブラリに含まれる atoi() 関数は、文字列を整数値に変換するために使用される関数です。文字列を引数として受け取り、対応する整数型の値を返します。

構文

int atoi(const char string)

パラメータと戻り値

パラメータ: atoi() 関数は、整数に変換対象となる文字列を入力として受け取ります。

戻り値: この関数は整数値を返します。入力された文字列が有効な数値文字列であれば、その整数相当の値が返されます。無効な文字列の場合は 0 が返されます。

atoi() の実装の考え方

独自の atoi() を実装する際の基本的なアプローチは以下の通りです。

まず、文字列の各文字を先頭から順に処理していきます。各ステップで、それまでの結果に10を掛け、現在の文字に対応する数値を加算することで整数を組み立てていきます。これは「桁をずらしながら数字を積み重ねる」処理です。

負の整数に対応するためには、文字列の最初の文字がマイナス記号(-)であるかどうかをチェックします。もしマイナス記号で始まっている場合は、最終的な結果に -1 を掛けることで負の値にします。

また、文字列が有効かどうかの判定も行います。具体的には、各文字が '0' から '9' の範囲内にあるかどうかを確認し、範囲外の文字が見つかった場合は無効な文字列として 0 を返します。

実装例

上記のロジックを実際に実装したプログラムが以下です。

#include <iostream>
using namespace std;
bool isNumericChar(char x) {
    return (x >= '0' && x <= '9') ? true : false;
}
int myAtoi(char* str) {
    if (*str == '\0')
       return 0;
    int result = 0;
    int sign = 1;
    int i = 0;
    if (str[0] == '-') {
        sign = -1;
        i++;
    }
    for (; str[i] != '\0'; ++i) {
        if (isNumericChar(str[i]) == false)
           return 0;
        result = result * 10 + str[i] - '0';
    }
    return sign * result;
}
int main() {
    char string[] = "-32491841";
    int intVal = myAtoi(string);
    cout<<"与えられた文字列の整数値は "<<intVal;
    return 0;
}

実行結果

与えられた文字列の整数値は -32491841

コードの解説

このプログラムでは、まず補助関数 isNumericChar() を定義し、渡された文字が数字('0'〜'9')であるかを判定しています。

メインの変換処理を行う myAtoi() 関数では、以下の手順で変換を行います。

1. 空文字列の場合は即座に 0 を返します。
2. 先頭文字が '-' であれば符号フラグを -1 に設定し、処理位置を1つ進めます。
3. 残りの文字を順番に走査し、数字以外の文字が見つかった時点で 0 を返します。
4. 各文字については、「これまでの結果 × 10 + (現在の文字 − '0')」という計算で数値を累積していきます。
5. 最後に符号を掛けた値を返します。

このように、標準ライブラリの atoi() と同等の動作を、シンプルなループ処理だけで自作することができます。実際の業務コードではオーバーフロー対策や空白文字のスキップなども考慮する必要がありますが、基本的な仕組みを理解するにはこの実装が非常に分かりやすい例となっています。

  1. C++で文字列をトークン化(分割)する2つの方法を解説

    文字列のトークン化(分割)とは、1つの文字列を区切り文字(スペースやカンマなど)を基準に、複数の部分文字列へ分割する処理のことです。C++では、標準ライブラリだけでもいくつかの方法で実現できます。本記事では、代表的な2つの方法をサンプルコード付きで紹介します。方法1:stringstreamを使って空白で分割する1つ目の方法は、stringstreamを使ってスペースで区切られた単語を順に読み取る方法です。この方法はやや制限がありますが、適切なチェックを加えれば十分に目的を果たすことができます。サンプルコード#include <vector> #include <string

  2. Rubyで学ぶ!シーザー暗号エンコーダーの自作方法

    シーザー暗号(Caesar cipher)をご存知ですか? これは、ユリウス・カエサルが敵に知られないよう秘密のメッセージを隠すために実際に使った暗号化手法です。 シーザー暗号は、最も原始的な暗号技術の一つとされています。 その仕組みの核心は、アルファベットの文字をx個分だけずらす(ローテートする)というシンプルなアイデアにあります。 例えば x = 1 の場合、「A」は「B」に、「C」は「D」に変換されます。以下同様です。 では、これをコードで実装するにはどうすればよいのでしょうか? 答えは意外と簡単です。文字は数値(ASCIIコード)として表現できるという事実を利用すれば、文字の回転処理