2012-04-07 29 views
0

大きなプログラムの一部として、数値の文字列を整数(最終的には浮動小数点数)に変換する必要があります。残念ながら私はキャスト、またはatoiを使用することはできません。数字の文字列を任意の整数の形式に変換する

私はこの線に沿って簡単な操作と思った:

void power10combiner(string deciValue){ 
    int result; 
    int MaxIndex=strlen(deciValue); 
     for(int i=0; MaxIndex>i;i++) 
     { 
      result+=(deciValue[i] * 10**(MaxIndex-i)); 
     }  
} 

が働くだろう。 charをintに変換するにはどうすればよいですか?私はASCII変換を使用することができると思いますが、変換メソッドが各ASCII番号の背後に異なる数値を返す膨大なifステートメントを持つと仮定して、intにcharを追加することはできません。

+4

ようこそStackOverflow!あなたは「許可されていない」と言っています。あなたの上司、あなたのコンパイラ、または教授があなたを制限していますか?あなたの教授の場合は、あなたの質問に '宿題'タグを追加してください。 –

+0

コードに若干の問題があります。まず、C++では指数演算子に '**'演算子はありません。次に、 'std :: string'は' strlen() 'のパラメータとして使用できません。代わりに 'deciValue.size()'を使いたいかもしれません。 –

答えて

0

提案で編集し、少し説明を追加しました。

int base = 1; 
int len = strlen(deciValue); 
int result = 0; 
for (int i = (len-1); i >= 0; i--) { // Loop right to left. Is this off by one? Too tired to check. 
    result += (int(deciValue[i] - '0') * base); // '0' means "where 0 is" in the character set. We are doing the conversion int() because it will try to multiply it as a character value otherwise; we must cast it to int. 
    base *= 10; // This raises the base...it's exponential but simple and uses no outside means 
} 

これは、文字列が数字のみであることを前提としています。より明確にする必要がある場合はコメントしてください。

+0

魔法の '0x30'とは何ですか?確かに移植性がありません。 –

+0

@KerrekSB strlen()はASCII文字列で動作します。 ASCIIは非常にポータブルです。 0x30は数字の0から9までの数字です。 0x30を減算し、数字は0-9になります。投稿者が気をつけているのは別の話ですが、ASCII文字列でも動作するatoiについて言及しています。私はちょうど数学をした...それを得る? –

+0

OPは恐らくエンコーディングについてさらに混乱しますが、これらの値をハードコードする理由は絶対にありません。「0」は完全にうまくいくでしょう。 –

2

これにはさまざまな方法があります。機能には最適化と修正がいくつかあります。

1)関数から値を返さないので、戻り値の型はintになります。

2)この関数を最適化するには、const参照を渡します。

次に例を示します。

std::stringstreamを使用して変換を行います。変換を行うにはstd ::にstringstreamを使用せずに

int power10combiner(const string& deciValue) 
{ 
    int result; 

    std::stringstream ss; 
    ss << deciValue.c_str(); 

    ss >> result; 

    return result; 
} 

int power10combiner(const string& deciValue) 
{ 
    int result = 0; 
    for (int pos = 0; deciValue[pos] != '\0'; pos++) 
     result = result*10 + (deciValue[pos] - '0'); 

    return result; 
} 
+0

彼の教授がatoiを使わないように言っていれば、std :: stringstreamも出ていると言っても間違いないと思いますが、それは私が作っている前提です。これは組み込み関数の代わりにアルゴリズムを使って作業するエクササイズのようです。 –

+0

@OrgnlDave:そうかもしれないが、彼は具体的ではなかったので、私はそうでなければ答えようと思った。 – josephthomas

+0

まあ、彼が探している答えは、彼は今それを持っています。あなたか私 - C++のビルトインか、私は疲れています。 :-D –

0

あなたは、単に任意の数のベースのため、場所値システムを実装して整数に反復的に文字列を解析することができます。あなたの文字列がnull終端であると仮定すると、その数は符号なし:

unsigned int parse(const char * s, unsigned int base) 
{ 
    unsigned int result = 0; 
    for (; *s; ++s) 
    { 
     result *= base; 
     result += *s - '0'; // see note 
    } 
    return result; 
} 

書かれているように、数字0を使用して10までの数拠点については、この唯一の作品、...、9、順番に配置されることが保証されていますあなたの実行文字セットで。より大きな数の基数またはより自由なシンボルセットが必要な場合は、指定された行の*s - '0'を、入力文字の桁の値を決定する適切なルックアップメカニズムで置き換える必要があります。

+0

私はあなたが(* s)の間に意味すると思う。 –

+0

また、const charポインタをインクリメントしています... –

+0

Graw、私は他の人々のほとんどが有効なコードをニックピッキングするのが悪いと感じています。私は代わりにいくつかの代理人を獲得する必要があります。 :-D –

0

私はstd :: stringstreamを使用しますが、誰もstrtolを使用したソリューションをまだ投稿していません。これは、範囲外のエラーを処理しないことに注意してください。 unix/linuxでは、errno変数を使用してそのようなエラーを検出することができます(それをERANGEと比較することによって)。

ところで、浮動小数点数にはstrtod/strtof/strtold関数があります。

#include <iostream> 
#include <cstdlib> 
#include <string> 


int power10combiner(const std::string& deciValue){ 
    const char* str = deciValue.c_str(); 
    char* end; // the pointer to the first incorrect character if there is such 
    // strtol/strtoll accept the desired base as their third argument 
    long int res = strtol(str, &end, 10); 

    if (deciValue.empty() || *end != '\0') { 
     // handle error somehow, for example by throwing an exception 
    } 
    return res; 
} 

int main() 
{ 
    std::string s = "100"; 

    std::cout << power10combiner(s) << std::endl; 
} 
関連する問題