Itoa not working in my compiler so I am looking for a an alternative which i found this error

itoa function is not defined in cygwin so i need to define one manually listed below"found in net" but I have an error saying
'can not convert std:basic-string<char>,std::char-traits<char>,std::allocator<char>>' to char* in intilization'
, basically I want to read multi files in one function readfrom_policyfile which takes integer and return string or char and put it in in the filename like file0.txt, file1.txt


readfrom_policyfile(int id)
{
std::string buffer;
buffer=itoa(id,10);

string *filename = "file"+id+".txt";
///
...}


std::string itoa(int value, int base) {

std::string buf;

// check that the base if valid
if (base < 2 || base > 16) return buf;

enum { kMaxDigits = 35 };
buf.reserve( kMaxDigits ); // Pre-allocate enough space.

int quotient = value;

// Translating number to string with base:
do {
buf += "0123456789abcdef"[ std::abs( quotient % base ) ];
quotient /= base;
} while ( quotient );

// Append the negative sign
if ( value < 0) buf += '-';

std::reverse( buf.begin(), buf.end() );
return buf;
}
Last edited on
Maybe you don't want a pointer to a string on line 6 (string *filename = "file" + id + ".txt")?
If ltoa() is not available, you could use sprintf() instead.

This would be a reasonable solution as you're wanting to generate names of the form file1.txt.
I agree with andywestken in that sprintf() is what you should be using, but if you must have a function that can translate from bases other than 8 (octal), hexadecimal (16) and decimal (10), you can roll your own itoa() function when it's not already available. For example, here is one that returns a std::string instance:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <string>

std::string
itoa (const int value,
      const unsigned int base=10,
      const bool printf_style=true)
{
  const char *base_key = "0123456789abcdef";
  std::string s = "0";
  unsigned int v = value;

  if (base >= 2 && base <= 16 && value)
    {
      s = "";
      if (value < 0 && (base == 10 || !printf_style))
        v = -value;

      while (v != 0)
        {
          s.insert (s.begin (), 1, base_key[v % base]);
          v /= base;
        }
    }

  if (value < 0 && (base == 10 || !printf_style))
    s.insert (s.begin (), 1, '-');
  return s;
}


Usage:
1
2
3
4
5
6
7
8
9
10
cout << itoa(22) << endl;              //value converted using default base (10)

cout << itoa(0xa0, 16) << endl;        //value converted using base 16

cout << itoa(-69) << endl;             //value < 0 converted using default base (10)

cout << itoa(-0xa0, 16) << endl;       //value < 0 converted using base 16

cout << itoa(-0xa0, 16, true) << endl; //value < 0 converted using base 16 and
                                       //  displayed in a more "normal" form 


Output:
22
a0
-69
ffffffa0
-a0
1
2
3
4
std::string
itoa (const int value,
      const unsigned int base=10,
      const bool printf_style=true)


Hi just curious, since the parameters are pass-by-value, making it const seems redundant since the calling program original variables would not have changed inside itoa function as a copy is made and passed in instead.

The time when const is useful IMHO is when we passed by pointer and reference and we want to ensure the calling program original variables are not changed inside itoa function.

e.g
itoa(const int& ref, ...)

Of cuz you can still put const int as parameters so was thinking is it a habit you adopt for all pass-by-value parameters ?

There is no need to make pass-by-value parameters const in order to protect the caller's data of course. However, if you want to prevent the called function from changing the values of the arguments passed to it then one would have to make them const.
A copy is made inside the function because the original value is needed to determine whether a sign is needed or near the end of the function. Why not do it at the beginning? It complicates the code a bit more to add the sign in the beginning whereas the code posted is relatively simple to follow and fairly succinct given the flexibility of the function.

The fact that a copy of the original value is needed means that it can be qualified with the const keyword. This allows the compiler to optimize the code more when possible on an architecture. For POD types such as int and bool, this is usually irrelevant, but sometimes it is useful when the function is called several times as in a loop.

Aside from the possible optimizations, it is in fact a personal habit to qualify parameters with the const keyword when it doesn't complicate the code too much, even POD types. :)
Thank you guys
It may seem out-dated but for the sake of public knowledge (if somebody viewed this thread later):

You can use std::stringstream defined in sstream for type conversion.

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>
#include <sstream>

int main ()
{
    int number = 2011;

    std::string text = "";

    std::stringstream stringBuffer (std::stringstream::in | std::stringstream::out);

    stringBuffer << number;

    stringBuffer >> text;

    std::cout << text << std::endl;

    return 0;
}


This should output "2011" as a std::string.
And for that little bit of extra completeness, as it's not been mentioned in this thread so far, you could use a boost lexical_cast.

See link to "Lexical Cast" on this page : http://www.boost.org
(the direct link is version specific so would have rotted)

The lexical_cast uses the stringstream to do it's work, but tidies up the use of this kind of approach. Note that it handles errors using exceptions.

Andy


Oops! I forgot that the lexical is only the other way! :-(
Last edited on
itoa is only supported in select and rare compilers. GCC for example doesn't support this feature. Possibly there's some ways of getting it but as I've heard, it's not that reliable. The alternative stated by this site is sprintf(str, "%d/x/u/etc", some other argument(10 sec later) oh yeah the damn thing you're turning into a string); -- sprintf(str, "%d", etc); But sprintf isn't very reliable either and a better alternative is the snprintf() function an extra argument of size_t or something is required. look in stdlib.h i believe. The c string library is very holy and you really need to watch what you do with it.

This is of course a c++ site. I would definitely suggest using some c++ features like string :p

Ah I just read your code and wanted to repeat what i just learned a few hours ago. How does string exactly work in c++ -- are they by default static pointers lik3 char? Doesn't a pointer to a string need to point to another string. You're actually assigning it a string value which is probably wrong. As pointer <string> types are much different than actual string types.

if statement asking if < 2 or > 16 is somewhat problematic. Having base numbers of 7 isn't necessarily a good thing

Someone explain this line to me buf += "0123456789abcdef"[ std::abs( quotient % base ) ];?

Looks interesting
Last edited on
Oops! I forgot that the lexical is only the other way! :-(

No, lexical_cast goes both ways.

The lexical_cast uses the stringstream to do it's work, but tidies up the use of this kind of approach. Note that it handles errors using exceptions.

Fortunately, it does not use stringstream. That means lexical_cast is much faster and does not depend on C++ iostreams.

lexical_cast is the right solution here.
Fortunately, it does not use stringstream. That means lexical_cast is much faster and does not depend on C++ iostreams.

After a closer look: yes, the Boost lexical cast's don't use stringstream. But they do use other bits of iostream (I assume they avoid non-inline routes, though)

An edited snippet from <lexical_cast.hpp> (Boost 1.41.0) follows. It was this kind of code, which I saw in passing, that led me to think they might have co-opted stringstream for some of the work. But looking closer, I see it's another type of istream based class!

Andy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
            // Generic istream-based algorithm.
            // lcast_streambuf_for_target<InputStreamable>::value is true.
            template<typename InputStreamable>
            bool operator>>(InputStreamable& output)
            {
                if(is_pointer<InputStreamable>::value)
                    return false;

                this->setg(start, start, finish);
                std::basic_istream<CharT> stream(static_cast<Base*>(this));
                stream.unsetf(std::ios::skipws);
                lcast_set_precision(stream, static_cast<InputStreamable*>(0));

                return stream >> output &&
                    stream.get() ==
                Traits::eof();
            }

Last edited on
Topic archived. No new replies allowed.