0

There must be an easy way to do this...

// C# code
    for (int i = 0; i < 20; i++)
        doSomething(i.ToString() + "_file.bmp");

I'm trying to do this in C++, but it turns out that the simplest things are the hardest to do in that language. Mostly because there's a catch: I'm restricted to a library that only takes char*'s as the parameter for the function this will eventually end up in, so I'm pretty much stuck playing with char arrays. This is what I have so far:

char* path[12];
for(int i = 0; i < 20; i++)
{
    sprintf(path[0],"%i_Card.bmp",i);
    cards[i] = new Card(i,path[0]);
}

The problem is, this approach ends me up with one big, long, useless string.

I must disclose that this is for a school assignment, but answering this question will not decide my grade, it will just make one aspect of the app a little easier.

selbie
  • 100,020
  • 15
  • 103
  • 173
Stephen Collins
  • 3,523
  • 8
  • 40
  • 61
  • 1
    You're not necessarily stuck with `char*` -- `std::string` has a method `c_str` to return a `char*` with the same contents – Ismail Badawi Sep 27 '11 at 05:18
  • Eh, no. `c_str` returns a `const char*`. Quite different; if the library tries to write to the `char*` you'll have issues. – MSalters Sep 27 '11 at 07:52

6 Answers6

7

The C++03 equivalent of ToString is

std::stringstream stream;
stream << i;
std::string i_as_string = stream.str();

Note that you can also accomplish that with no intermediate variables, by doing ( std::stringstream() << i ).str().

In C++11 there is both std::lexical_cast< std::string >( i ) which does the above for you (also available from Boost), and std::to_string( i ).

K-ballo
  • 80,396
  • 20
  • 159
  • 169
5

Try this

#include <stdio.h>
#include <stdlib.h>

itoa(i)

atoi


Or you can go this route:

#include <sstream>

int i = 5;
std::string s;
std::stringstream out;
out << i;
s = out.str();
Community
  • 1
  • 1
qwertymk
  • 34,200
  • 28
  • 121
  • 184
  • The link caption should be `itoa` not `atoi` – qwertymk Sep 27 '11 at 05:51
  • 1
    From the linked `itoa` page: "**not** part of C++". – MSalters Sep 27 '11 at 07:53
  • @MSalters: Does that bother you? I guess you *could* use a `stream` and it will take 3 lines of code as opposed to 1 line, but in case you **need** everything in a c++ program to be `c++` and not at all `c`, then you can use the second technique i gave. BTW what do you do for `int` in `c++`, `int` is a part of `c` – qwertymk Sep 27 '11 at 11:40
  • 1
    It's not part of C, either. Didn't quote that part, as it's obvious (The C library is part of C++) and irrelevant (question is tagged C++, not C). – MSalters Sep 27 '11 at 12:38
  • If the streams approach is too long for you, wrap it (see `lexical_cast`). – Georg Fritzsche Sep 27 '11 at 23:37
1

I see several bugs in your code.

1) You declare "path" to be an array of 12 character pointers, but no memory allocated for the any of the array items. The sprintf statement is guaranteed to copy into garbage memeory. I'm surprised this doesn't crash your program right away.

2) And even if there was memory allocated for the path array, your sprintf statement always copies to path[0] - overwriting what was already there.

I suspect you are confusing char arrays, strings, and arrays of strings in C/C++. Perhaps the code below will help. I'm assuming that your "Card" class doesn't save a copy of the string passed as the second parameter to a member variable (at least not without copying it). Otherwise, it will be pointing to stack memory - which could be buggy if your Card instance outlives the function in which it was created in.

const size_t MAX_INTEGER_LENGTH = sizeof(int) * 4; // 4x the sizeof int will suffice no matter what the sizeof(int) is

char szPostfix[] = "_Card.bmp"; 

for(int i = 0; i < 20; i++)
{
    char path[MAX_INTEGER_LENGTH + sizeof(szPostfix) + 1]; //+1 for null terminator
    sprintf(path,"%d%s",i, szPostfix);
    cards[i] = new Card(i,path);
}
selbie
  • 100,020
  • 15
  • 103
  • 173
  • One problem, though. I can't pass a const char* to the function called in Card's constructor. It only accepts char*'s. – Stephen Collins Sep 27 '11 at 05:45
  • Ahh, but "path" is not a "const char*". I don't think you understand that that arrays and pointers are nearly one in the same in C/C++. For all intents and purposes, "path" is declared as an array of characters. But when arrays are passed into functions, they "gracefully degrade into pointers". In this case, "path" gets passed to Card as if it was a "char *". The above code works. Trust me. The only concern I would have is if Card constructor modifies the contents of path before it returns or if it holds on to that pointer address. – selbie Sep 27 '11 at 06:15
  • This works perfectly and does everything I need it to! Thanks a ton! – Stephen Collins Sep 28 '11 at 04:13
  • Great. I just hope you have learned the relationship between arrays, pointers, and strings in C. – selbie Sep 28 '11 at 04:26
0

You can use std::string and convert it to to the c-string using std::string::c_str(). However, it returns a c string of const char*. const_cast can be use to disqualify the const associated with it.

#include <iostream>
#include <string>
using namespace std;

void foo(char* str){
    cout << str << endl;
}

int main(){

    string str = "Hello World";
    foo(const_cast<char*>(str.c_str()));

    return 0;
}

Output: Hello World

Demo

Mahesh
  • 34,573
  • 20
  • 89
  • 115
0

There's no general way to convert an object to a string in C++. You have to define your conversion functions yourself. For basic types you can convert them to strings using stringstream.

#include <sstream>
#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{
  stringstream ss;
  ss << 1;
  cout << ss.str();
}

There's more info about stringstream here

sashang
  • 11,704
  • 6
  • 44
  • 58
0

From the code it looks like it is a file name and the Card class should take the path as a const char*. So I think the following would be the c++ way of doing it.

for(int i = 0; i < 20; i++)
{
    std::stringstream out;
    out << i << "_Card.bmp";
    cards[i] = new Card(i,out.str().c_str());
}
balki
  • 26,394
  • 30
  • 105
  • 151