2012-04-17 38 views
3

文字列を16進数に変換するはずのC++プログラムを実行しています。それはコンパイルされますが、実行時のエラーは次のようになります。C++添え字範囲外

デバッグアサーションが失敗しました! (ああ!)

のVisual Studio2010 \ 1440

ラインをXSTRING \含まれます:文字列の添字範囲

のうち、そして、私は中止する選択肢がない...それはそうですそれはエラーの時点までそれを変換するので、私は何が起こっているのか分からない。私のコードはシンプルです:

#include <iostream> 
#include <iomanip> 
#include <string> 
using namespace std; 
int main() 
{ 
    string hello = "Hello World"; 
    int i = 0; 
    while(hello.length()) 
    { 
     cout << setfill('0') << setw(2) << hex << (unsigned int)hello[i]; 
     i++; 
    } 

    return 0; 
} 

このプログラムは、各文字を16進数に変換する必要があります。

答えて

4

あなたのwhile条件が正しくありません:

while(hello.length()) 

ループが終了したことがないとiが大きい(文字列の長さから1を引いたものよりも)になり、あなたがそのインデックスで文字列にアクセスするときに、ランタイム・アサーションを取得します。

に変更し、それを:

while(i < hello.length()) 

またはそれ以上の使用イテレータ。

+0

ああ、なぜそれがコンパイルされ、そんなに奇妙なエラーメッセージが出るのですか? (thanks btw) –

+0

@ Howdy_McGeeコンパイラは実行時エラーを探すはずなので、 'while'式に定数またはローカル変数がある場合、警告が表示されることに注意してください。しかし、関数呼び出しによって、データが変更される可能性があるとコンパイラは判断します。 – littleadv

2
while(i < hello.length()) 
    { 
     cout << setfill('0') << setw(2) << hex << (unsigned int)hello[i]; 
     i++; 
    } 

元のループは終了しません。インデックスをカウントするには、forのループ構文が適しているとわかります。

+1

あなたは最初に答えましたが、あなたはアップフォートを取得していませんでした! +1 –

+0

@Jesse thanks :)時々、私は誰がより速く撃つかの競争にいるように感じます。 – littleadv

6

文字列から何も削除していないので、length()は常にtrueに変換される同じ番号を返します。

ではなく、forループを使用してください:

for(int i = 0; i < hello.length(); ++i) 
{ 
    cout << setfill('0') << setw(2) << hex << (unsigned int)hello[i]; 
} 

あるいはさらに良いと、イテレータを使用しています。

for(std::string::iterator it = hello.begin(); it != hello.end(); ++it) 
{ 
    cout << setfill('0') << setw(2) << hex << *it; 
} 
0

whileループの条件がありません。

while(i < hello.length()) 
    { 
     cout << setfill('0') << setw(2) << hex << (unsigned int)hello[i]; 
     ++i; 
    } 
0

forループでイテレータを使用したいと思います。

for (std::string::const_iterator it = hello.begin(); it != hello.end(); ++it) { 
    // String processing 
} 

あるいは、C++ 11で:一般的に

for (char const c : hello) { 
    // String processing 
} 

、私は可能な限りC++で物事にアクセスするためのイテレータを使用することを好みます。これはもっと慣用的な方法であり、すべてのタイプのSTLコンテナで機能します。たとえば、ある日にstd::dequeまたはstd::listを使用する場合、イテレータは引き続き動作します。

別のスタイルノートでは、私はCスタイルのキャストを避けるでしょう。それは(unsigned int)の場所です。代わりに、static_cast<unsigned> (*it)を使用してください。これは、あなたが実際に行っているキャスト能力を与えるだけであなたの意図を伝えます。 Cスタイルのキャストははるかに広いですが、ここで必要なのは、整数型のサイズを変換することだけです。

関連する問題