0

This is very strange. itoa(); seems to create an infinite loop.

for(int i = 0; i < 10; i++)
{
        char buffer[1];
        itoa(i, buffer, 10);
        std::cout << buffer;
}

Why on earth does it do that? I've tried using different variables than i, numerical values without variables (i.e. itoa(1, buffer, 10);), it still keeps ending up in an infinite loop. I've tried to google without much success, I found an old mail about it here. I am using Windows XP 32 bit and Code::Blocks (with GCC) as a compiler.

Does anyone know what's wrong? Thanks in advance.

Griffin
  • 644
  • 6
  • 18
  • Try `boost::lexical_cast` instead. – Tom Kerr Oct 25 '11 at 21:51
  • 1
    Or stringstreams directly (which lexical_cast uses). – Xeo Oct 25 '11 at 21:53
  • 2
    `itoa` isn't a standard function and really you should avoid it. `snprintf()` is a safe way to do what you're doing, as well as a number of others. – Brian Roach Oct 25 '11 at 21:53
  • @Xeo : `lexical_cast` was changed some time ago to be implemented in terms of `sprintf`/`snprintf` for primitive types due to the poor performance of standard IO streams. – ildjarn Oct 25 '11 at 21:54
  • @BrianRoach, I'll check out `snprintf()`. Thanks for your comment. – Griffin Oct 25 '11 at 21:56
  • @ildjarn: Oh, thanks for the info. It really makes me wonder if the extensibility and type safety of IO streams can be matched with the speed of the C functions... – Xeo Oct 25 '11 at 21:58
  • @Xeo : Of course -- even **faster** than the C functions, in fact! (though at the expense of compile times) [Boost.Spirit.Karma](http://www.boost.org/libs/spirit/doc/html/spirit/karma/tutorials/quick_start.html) :-) (See specifically [these benchmarks](http://www.boost.org/libs/spirit/doc/html/spirit/karma/performance_measurements/numeric_performance.html).) – ildjarn Oct 25 '11 at 22:00
  • 1
    Since when does GCC support itoa? – Don Reba Oct 25 '11 at 22:08
  • @DonReba So it's not supported? I had no idea, how come it compiles then? Obviously there's some sort of reference to it since it actually loops, hmmm oh well. Thanks for your comment. – Griffin Oct 25 '11 at 22:11
  • @ildjarn: I really need to look into Boost.Spirit sometime... Though, to be fair, their code for iostreams is not really fair thanks to the constant reset of the stream, though I don't have any better way currently in mind. – Xeo Oct 25 '11 at 22:16

3 Answers3

5

itoa null-terminates the string it produces, but you haven't made buffer large enough to hold the terminating NUL character. Try:

for (int i = 0; i < 10; i++)
{
    char buffer[2];
    itoa(i, buffer, 10);
    std::cout << buffer;
}
ildjarn
  • 62,044
  • 9
  • 127
  • 211
  • @ildjarn Already tried that, it didn't work. Sorry, I guess I should've mentioned it (didn't do it because I knew it was going to be a terminating null there, but to try different stuff). Thanks for your answer. – Griffin Oct 25 '11 at 21:52
  • @Xeo, a three byte char ends up in an infinite loop aswell. – Griffin Oct 25 '11 at 21:53
  • 1
    @Griffin : This works as a standalone example, so if it doesn't work for you then it's related to code you've not shown us, or you have a faulty build environment. – ildjarn Oct 25 '11 at 21:58
  • @ildjarn Very strange, as I only have an unused function (which I just commented out). Other than that, that's the only code I have except for library inclusions and the `main()` function and `return 0;`. – Griffin Oct 25 '11 at 22:02
  • I suppose my build environment is a different topic, so I'll just go ahead and give you an accepted answer. Thank you very much for your help, @ildjarn. – Griffin Oct 25 '11 at 22:08
1

Why on earth are you using a general number conversion routine for single digits?

for (int i = 0; i < 10; i++)
    std::cout << char('0' + i);

(You need the cast back to char so that the compiler uses the correct overload of <<. The C++ standard guarantees that the character constants '0' through '9' have consecutive numeric values.)

zwol
  • 135,547
  • 38
  • 252
  • 361
  • My original post was only a quick example, I'm going to use `itoa()` for much larger numbers (characters) in my real program. 52 possible characters, to be precise. Thank you for your answer. – Griffin Oct 25 '11 at 22:34
  • Oh, well, in that case, yeah, you want `snprintf`. Or just give up on iostreams and use good old `[f]printf`. Iostreams are not enough better than stdio.h to be worth using, in my opinion. – zwol Oct 26 '11 at 00:04
  • @Zack : Type safety is not something to be shrugged off. – ildjarn Oct 26 '11 at 00:56
  • Type safety is nice, but it's not enough of a benefit to compensate for the verbosity and the awkward and the missing features. – zwol Oct 26 '11 at 02:55
0

Your buffer is too small -- itoa will write a null-terminated string, so your buffer will need at a minimum 2 bytes to hold values from 0-9.

Joe
  • 41,484
  • 20
  • 104
  • 125