0

I have three char arrays. Each of them represents one part of a big file name I would like to have in the end.

For that matter I want to concatenate these char arrays into one big array to pass it onto cImage.Save as file name.

Here's what I got to build up the strings:

// Time
time_t rawtime = time(NULL);
struct tm timeInfo;

// Strings
char path[sizeof("G:\\screenify_images\\")] = { "G:\\screenify_images\\" };
char fileName[128] = { 0 };
char fileExtension[16] = { ".jpeg" };

// Get current time and save it as string
localtime_s(&timeInfo, &rawtime);
strftime(fileName, 128, "%X", &timeInfo);

cout << "Path:" << path << endl << "FileName:" << fileName << endl << "Extension:" << fileExtension << endl;

// Memory for our new, final string
char *fullPath = new char[strlen(path) + strlen(fileName) + strlen(fileExtension) + 1];
strcat_s(fullPath, 128, path);
strcat_s(fullPath, 128, fileName);
strcat_s(fullPath, 16, fileExtension);

Unfortunately it's either not working at all (not even throwing errors, just hanging up) or the full name has some weird chars in the beginning. I fear this has to do with me allocating memory not correctly or some other mistake.

Any help is welcome!

Philipp Meissner
  • 5,273
  • 5
  • 34
  • 59
  • 6
    Is there some reason you are using C style char arrays instead of C++ style strings? – Beta Aug 23 '15 at 17:42
  • Change the first `strcat_s` call to `strcpy_s`; or else initialize `fullPath` so it's NUL-terminated before the first call. Better still, start using `std::string` et al. – Igor Tandetnik Aug 23 '15 at 17:43
  • Try using string stream. It is comfortable and in C++ way when it come to concatenation – Anjenson Aug 23 '15 at 17:47
  • @igor - Neither of these approaches made it work, it even game errors because the destination must not be NULL (eg, if I initialize fullPath with {0}). – Philipp Meissner Aug 23 '15 at 17:49
  • @Anjenson - May you give me a little more of a hint? Do you speak about stringstream here? :) – Philipp Meissner Aug 23 '15 at 17:49
  • 1
    I didn't say `fullPath` should be `NULL`. I said it should point to a NUL-terminated string. That's not at all the same thing. Make it `char *fullPath = new ...; fullPath[0] = 0;` Also, the second parameter of `strcat_s` is the size of the buffer that the *first* parameter points to, not the last. You are lying to the function there. – Igor Tandetnik Aug 23 '15 at 17:52
  • 2
    Go with `std::string`s, but for future reference, `char path[sizeof("G:\\screenify_images\\")] = { "G:\\screenify_images\\" };` is unnecessarily complex. `char path[] = "G:\\screenify_images\\";` is sufficient. The compiler will figure out the size for you. – user4581301 Aug 23 '15 at 18:14

2 Answers2

3

Since this question is tagged C++, the right way to concatenate these "char arrays" is to not have them be char arrays:

// Strings, for real
std::string path = "G:\\screenify_images\\";
std::string fileExtension = ".jpeg";

std::string fileName(128, 'x');
fileName.resize(strftime(fileName.data(), fileName.size(), "%X", &timeInfo));

// either
std::string fullPath = path + fileName + fileExtension;

// or
std::ostringstream oss;
oss << path << fileName << fileExtension;
// use oss.str()

Note that you don't even need to save the other fragments if you don't want to:

oss << "G:\\screenify_images\\"
    << fileName
    << ".jpeg";
Barry
  • 286,269
  • 29
  • 621
  • 977
1

Using std::string you can freely append both char * strings and std::string strings with += or .append().

e.g.,

string path;
// path starts out empty, appending is the same as 
//  if definition of path had been "string path("/tmp/");
path.append("/tmp/");
string filename("afilename");
path.append(filename);
path += ".foo";
ewd
  • 167
  • 1
  • 9