1

I am making a PONG clone in C++/SDL, and I have all of my images in the directory in which the program starts. I am successfully able to find that path using GetCurrentDirectory() and open the file using strcat() to append the actual image and it will load fine, but this will change the original value, which makes it useless when I try to load the next image. How would I pass the path without changing the original value, or another way to work around this problem.

My current code:

    TCHAR openingdirectorytemp [MAX_PATH];
    bgtexturesurf = SDL_LoadBMP(strcat(openingdirectorytemp, "\\bg.bmp"));
genpfault
  • 51,148
  • 11
  • 85
  • 139
Jason Mills
  • 585
  • 2
  • 6
  • 20

4 Answers4

1

Use actual C++ strings:

#include <string>

using std::string;

void child(const string str)
{
  str += ".suffix"; // parameter str is a copy of argument
}

void parent()
{
   string parents_string = "abc";
   child(parents_string);
   // parents_string is not modified
}

If you must work with TCHAR in the Windows API world, use std::basic_string<TCHAR>:

typedef std::basic_string<TCHAR> str_t; // now use str_t everywhere

and so the code becomes something like

void my_class::load_bg_bmp(const str_t &dir_path)
{
  str_t file_path = dir_path + _T("\\bg.bmp")l
  bgtexturesurf = SDL_LoadBMP(file_path.c_str()));
  // ...
}

The TCHAR type allows for build times switching between narrow and wide characters. It is pointless to use TCHAR, but then use unwrapped narrow character string literals like "\\bg.tmp".

Also, note that strcat to an uninitialized array invokes undefined behavior. The first argument to strcat must be a string: a pointer to the first-element of a null terminated character array. An uninitialized array is not a string.

We can avoid such low-level nasties by using the C++ string class.

Kaz
  • 55,781
  • 9
  • 100
  • 149
0

Although you can use C++ string as suggested by other answers, you can still keep your C approach.

What you need to do is just to create another string by copying the contents from the original, and use it for strcat:

TCHAR openingdirectorytemp [MAX_PATH];
TCHAR path [MAX_PATH];
strcpy(path, openingdirectorytemp);
bgtexturesurf = SDL_LoadBMP(strcat(path, "\\bg.bmp"));

By doing so, you create string path with a separate memory space, so strcat won't affect openingdirectorytemp

Krypton
  • 3,337
  • 5
  • 32
  • 52
  • That seems to be the easiest way to do it, just for curiosity's sake, which is more efficient, using C++ strings or the array's of chars like I am and just copying them. I know any difference at this level is negligible, just curious. – Jason Mills Oct 09 '13 at 12:54
  • The C implementation IN THIS CASE is more efficient. C++ string is more for dynamic length string. Since path is of fix length (MAX_PATH), such handling incurs extra works and thus causes slower in performance. – Krypton Oct 09 '13 at 15:19
  • I think that inclusive in this case, C++ string is as efficient as C implementation, but, in general, prefer C++ string (http://stackoverflow.com/questions/12124263/efficiency-of-c-string-vs-cstrings). By the other way, never, ever use `strcpy` or `strcat`. Prefer its safers cousin `strncpy` and `strncat` (http://stackoverflow.com/a/6502352/2293156) – Amadeus Oct 09 '13 at 19:15
0

You need to make a copy of the string before concatenating if you are worried about things getting changed. In other words

string1 = "abc"
string2 = "def"
strcat(string1, string2);

Results in

string1 = "abcdef"

since that is what you asked the program to do. Instead, add

strcpy(string3, string1)
strcat(string3, string2);

Now you will have

string1 = "abc" 
string3 = "abcdef"

Of course you need to make sure enough space is allocated, etc.

Floris
  • 45,857
  • 6
  • 70
  • 122
0

Once you are using c++, you can use string to compose your final pathname:

string pathname(path);
pathname += "\\bg.bmp";

bgtexturesurf = SDL_LoadBMP(pathname.c_str());
Amadeus
  • 10,199
  • 3
  • 25
  • 31