3

我正在运行一个应该将字符串转换为十六进制的 C++ 程序。它编译但我在运行时出错说:

调试断言失败!(不好了!)

Visual Studio2010\include\xstring

1440线

表达式:字符串下标超出范围

而且我别无选择中止......它似乎将它转换为错误点,所以我不确定发生了什么。我的代码很简单:

#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;
}

这个程序应该做的是将每个字母转换为十六进制 - 逐个字符。

4

5 回答 5

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;
}
于 2012-04-17T06:14:50.763 回答
4

您的 while 条件不正确:

while(hello.length())

循环永远不会终止并i变大(超过字符串长度减一),当您访问该索引处的字符串时,您会获得运行时断言。

将其更改为:

while(i < hello.length())

或者更好地使用迭代器。

于 2012-04-17T06:15:04.970 回答
2
while(i < hello.length())
    {
        cout << setfill('0') << setw(2) << hex << (unsigned int)hello[i];
        i++;
    }

你原来的循环永远不会结束。对于计数索引,我发现for循环语法更适合。

于 2012-04-17T06:14:17.957 回答
0

您缺少 while 循环中的条件。

 while(i < hello.length())
    {
        cout << setfill('0') << setw(2) << hex << (unsigned int)hello[i];
        ++i;
    }
于 2012-04-17T06:17:18.870 回答
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::dequeor std::list,那么迭代器仍然可以工作。

在另一种风格上,我会避免使用 C 风格的转换。那是你做(unsigned int)的。相反,使用static_cast<unsigned> (*it). 这通过只给你你真正追求的施法能力来传达你的意图。C 风格的转换要广泛得多,但您在这里只需要在整数类型的大小之间进行转换。

于 2012-04-17T06:17:25.753 回答