Reputation: 10673
I'm running a C++ Program that is supposed to convert string to hexadecimals. It compiles but errors out of me at runtime saying:
Debug Assertion Failed! (Oh no!)
Visual Studio2010\include\xstring
Line 1440
Expression: string subscript out of range
And I have no choice to abort... It seems like it converts it though up to the point of error so I'm not sure what's going on. My code is simple:
#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;
}
What this program should do is convert each letter to hexadecimal - char by char.
Upvotes: 3
Views: 4490
Reputation: 53067
You're not removing anything from the string and so length()
will always return the same number which converts to true
.
Use a for loop instead:
for(int i = 0; i < hello.length(); ++i)
{
cout << setfill('0') << setw(2) << hex << (unsigned int)hello[i];
}
Or even better, use iterators.
for(std::string::iterator it = hello.begin(); it != hello.end(); ++it)
{
cout << setfill('0') << setw(2) << hex << *it;
}
Upvotes: 6
Reputation: 28893
I would prefer iterators here in a for loop.
for (std::string::const_iterator it = hello.begin(); it != hello.end(); ++it) {
// String processing
}
Or, in C++11:
for (char const c : hello) {
// String processing
}
In general, I prefer to use iterators to access things whenever possible in C++. It's the more idiomatic way to do it, and it works for all types of STL containers. For instance, if you want to some day use a std::deque
or std::list
, then iterators will still work.
On another style note, I would avoid C-style casting. That is where you did (unsigned int)
. Instead, use static_cast<unsigned> (*it)
. This conveys your intent by only giving you casting abilities that you are actually after. A C-style cast is much more broad, but all you want here is to convert between sizes of integer types.
Upvotes: 0
Reputation: 4534
You are missing the condition in while loop.
while(i < hello.length())
{
cout << setfill('0') << setw(2) << hex << (unsigned int)hello[i];
++i;
}
Upvotes: 0
Reputation: 455312
Your while condition is incorrect:
while(hello.length())
The loop never terminates and i
becomes large (more than string length minus one) and when you access the string at that index you get runtime assertion.
Change it to:
while(i < hello.length())
Or better use iterators.
Upvotes: 4
Reputation: 20282
while(i < hello.length())
{
cout << setfill('0') << setw(2) << hex << (unsigned int)hello[i];
i++;
}
Your original loop never ends. For counting indexes, I find the for
loop syntax better suited.
Upvotes: 2