help with function to concatenate strings (C++)

h4ever

Member
Aug 30, 2013
163
0
0
I have this function/method

Code:
char Setts::GetTempFileName(char fileName)
{
    std::string path = GetCurrentDirectory(_MAX_PATH, path) + "\\" + filename;
    return path;
}
Which makes incomaptibility errors.

I call it with this:
Code:
TempPath = GetTempFileName("scendata.tmp");
logname = GetTempFileName("ats_cache.log");
I want to get complete path to a file in current directory but I can not work with these things to convert strings. Can you help with it?
 
Last edited:

serpretetsky

Senior member
Jan 7, 2012
642
26
101
whats the code for GetCurrentDirectory?
how is _MAX_PATH defined?

you are declaring the string "path" and then feeding it uninitialized into GetCurrentDirectory?

whats "fileName" used for the in the function?
 

h4ever

Member
Aug 30, 2013
163
0
0
We can set _MAX_PATH to any number describing length of path e.g..

#define _MAX_PATH 42

Path is defined in Setts class:

Code:
extern class Setts
{
    char path[_MAX_PATH];
filename is argument of the function:

TempPath = GetTempFileName("scendata.tmp");
logname = GetTempFileName("ats_cache.log");

it is either "scendata.tmp" or "ats_cache.log"

I Expect path can be like
Code:
c:\my folder
... I want to add backslash and file name... defined by the function argument
 
Last edited:

serpretetsky

Senior member
Jan 7, 2012
642
26
101
welll, first of all "scendata.tmp" is not a char. It's a an array of chars. It can be considered a cstring. So maybe you meant
Code:
char Setts::GetTempFileName(char* fileName) //or
char Setts::GetTempFileName(char[] fileName)

But what I mean is, your method takes in "filename" but why? it doesn't do anything with filename. It takes in filename and then it's not mentioned anywhere in the rest of the function. What do you do with filename? right now it looks like it just hangs in midair doing nothing, and affecting nothing. You pass it as an argument and thats the end of that.

edit: lol, nevermind. My browser wasn't wide enough to see the whole line :D
edit edit: or you editted it in. Whichever :)
 
Last edited:

h4ever

Member
Aug 30, 2013
163
0
0
I forgot to add it or I lost the change I did.

Code:
char Setts::GetTempFileName(char fileName)
{
    std::string path = GetCurrentDirectory(_MAX_PATH, path) + "\\" + filename;
    return path;
}
 

h4ever

Member
Aug 30, 2013
163
0
0
After change to char* I got next error:

error C2664: 'GetCurrentDirectoryA' : cannot convert parameter 2 from 'std::string' to 'LPSTR'

that is the line
Code:
std::string path = GetCurrentDirectory(_MAX_PATH, path) + "\\" + filename;

But probably all should result in char* or char[_MAX_PATH], so probably std::string path was not good choice.
 
Last edited:

serpretetsky

Senior member
Jan 7, 2012
642
26
101
I see, in that case you must excuse my ignorance and excuse me from this thread after this post. I am not familiar with this function or these data types. Perhaps someone else will chime in with a little bit more knowledge.

However, the function you linked to says this
Return value
If the function succeeds, the return value specifies the number of characters that are written to the buffer, not including the terminating null character.
But you seem to be expecting a string returned. I think it writes the currentdirectory INTO the second parameter.

also, have you seen the function?
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364963(v=vs.85).aspx
it seems to get what you want done in a single function.

Well, again, my knowledge on microsoft stuff is limited so...

good luck!
 

Tweak155

Lifer
Sep 23, 2003
11,449
264
126
After change to char* I got next error:

error C2664: 'GetCurrentDirectoryA' : cannot convert parameter 2 from 'std::string' to 'LPSTR'

that is the line
Code:
std::string path = GetCurrentDirectory(_MAX_PATH, path) + "\\" + filename;

But probably all should result in char* or char[_MAX_PATH], so probably std::string path was not good choice.

Change the parameter filename to a string, the function itself from a char to a string, and make sure TempPath is also a string.
 

h4ever

Member
Aug 30, 2013
163
0
0
whats the function prototype for GetCurrentDirectory?

I found the definition of _MAX_PATH, it is:

#define _MAX_PATH 260

I add break point and I really can find the value of path, it is the directory where the program is compiled or run. So it works well.

But you seem to be expecting a string returned. I think it writes the currentdirectory INTO the second parameter.

The actual directory is saved to second argument of the GetCurrentDirectory function and then GetTempFileName returns (should return) full path with the filename.
 
Last edited:

h4ever

Member
Aug 30, 2013
163
0
0
Change the parameter filename to a string, the function itself from a char to a string, and make sure TempPath is also a string.

And if I decide to use char* as output type? It should be better because the project seems to use char* of char[_MAX_PATH] in the rest of code.

I see that I could not use + sign. But what is better? To use std::string to concatenate the strings or not to use + sign?
 
Last edited:

Tweak155

Lifer
Sep 23, 2003
11,449
264
126
And if I decide to use char* as output type? It should be better because the project seems to use char* of char[_MAX_PATH] in the rest of code.

I see that I could not use + sign. But what is better? To use std::string to concatenate the strings or not to use + sign?

You can use char* as they are technically equivalent. However strings have functions built into them. That is the main difference. It's been a very long time since I've done C++, but I think char* and string are interchangeable in a lot of places (i.e you can store a string into a char* and vice versa).

You just need to be consistent. It generally makes your life easier.
 

h4ever

Member
Aug 30, 2013
163
0
0
Anybody else can help? I need some example of code to concatenate the char* variables.
 
Last edited:

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
I ask if anybody else can help C++ I need some example of code to concatenate the char* variables.

You want to write your own function to concatenate strings of characters in C++? Go for it. You'll learn a lot. The first thing you need to do is decide whether the function is general purpose or specific to this use. That will inform other decisions you'll have to make. Then you'll have to decide on a memory management strategy. Those char*'s point to strings of characters in memory, either on the stack, on the heap, or in a data segment. You don't really care for this purpose where they are, but the point is they're just memory addresses, not objects with associated methods or properties.

So when you're done you're going to need to have read in the contents of memory at each of those locations, beginning with the first address and ending with the null terminator at the end of the string. Then you have to copy those bytes into a new buffer that is large enough to hold the full concatenated string when you're done. Finally you have to make sure there is a null terminator at the end.

It's the same task as any general buffer concatenation problem in C/C++, and encoding issues aside you can approach it the same way.

Or you can use the built in string class from the standard library. Which is probably what I would do :).
 

h4ever

Member
Aug 30, 2013
163
0
0
This is what I did and it work! My first concatenate!

But I need advice. Is it wise to use char* instead char[MAX_CHARS] with regards to use in path/file name strings?
I mean why to limit char? Is it for size of the program or memory it can consume?

header:
Code:
#include <stdlib.h>    //for _MAX_FNAME and the like if needed
#include <iostream>
extern class Setts
{
    char path[_MAX_PATH];    //Path to INI

public:
    Setts();~Setts();
    char* GetTempFileName(char*);
    bool load();

    //Not in ini
    char* BasePath;    //Path to the AOK directory
    char* ScenPath;    //Path to the currently open scenario

    // Path to decompressed file / temp
    char* TempPath;    //Path to the decompressed temp file
} setts;
And then the main code:

Code:
#define WIN32_LEAN_AND_MEAN // (not sure why this is in the project) 
#include <windows.h> // (not sure why this is in the project) 
#include "settings.h"
#include <stdio.h>

Setts::~Setts(){}

char* Setts::GetTempFileName(char* fileName)
{
    GetCurrentDirectory(_MAX_PATH, path);
    strcat(path, "\\");
    strcat(path, fileName);
    return path;
}

bool Setts::load()
{
// some code here using BasePath to get game version from register. Not important
}

    TempPath = GetTempFileName("scendata.tmp");
    logname = GetTempFileName("ats_cache.log");
    return (result == ERROR_SUCCESS);
}
Edit: I did not tested the result yet, but I will do later.
 
Last edited:

Tweak155

Lifer
Sep 23, 2003
11,449
264
126
And if that doesn't work...

Code:
#include <string.h>

Life gets easier at that point.
 

code65536

Golden Member
Mar 7, 2006
1,006
0
76
#define WIN32_LEAN_AND_MEAN // (not sure why this is in the project)
That just reduces the number of header files that are included (and parsed by the compiler). The only thing it does is speed up compilation; unless you doing a large project (the kind that can takes minutes to compile instead of a second), there is no point in having this.

But I need advice. Is it wise to use char* instead char[MAX_CHARS] with regards to use in path/file name strings?
The former requires that you manage memory, but it's flexible. Determine the length of your path, allocate the memory, and free that memory once you're done (unless you like memory leaks). With the latter, you have to enforce that limit. Which, BTW, strcat does not do, so it's possible to overflow that buffer in your code, in which case Bad Things (TM) can happen. You can use strcat_s (which is specific to Microsoft's compiler) or manually check and enforce lengths.



Also, I just want to say that I personally don't like the way most educators teach C/C++ by having people jump right into C++ doing things like classes and using the C++ standard library. People really should start with just C and get used to pointers, memory management, pointers, how strings and arrays physically exist in the world of low-level programming, pointers (and did I mention pointers?), and only with that foundation should they use C++. I've seen way too many people confused when they try navigate the ugly world of C++ without knowing the "C" part of "C++".
 
Last edited:

h4ever

Member
Aug 30, 2013
163
0
0
That just reduces the number of header files that are included (and parsed by the compiler). The only thing it does is speed up compilation; unless you doing a large project (the kind that can takes minutes to compile instead of a second), there is no point in having this.


The former requires that you manage memory, but it's flexible. Determine the length of your path, allocate the memory, and free that memory once you're done (unless you like memory leaks). With the latter, you have to enforce that limit. Which, BTW, strcat does not do, so it's possible to overflow that buffer in your code, in which case Bad Things (TM) can happen. You can use strcat_s (which is specific to Microsoft's compiler) or manually check and enforce lengths.

OK, that helps. I will use the latter.
 

h4ever

Member
Aug 30, 2013
163
0
0
Guys, I have found one class to work with files in the project:

Code:
class AutoFile
{
public:
    AutoFile(FILE * file);
    AutoFile(const char * filename, const char * mode);
    ~AutoFile();

    FILE * get();

    /**
     * Close the file. Further calls to get() will return NULL.
     */
    void close();

private:
    AutoFile(const AutoFile&); // no copy constructor!

    FILE * _file;
};

What surprises me that it can be used like this:

Code:
AutoFile tempout(dpath, "wb");
AutoFile scx(path, "wb");
AutoFile temp(dpath, "rb");
AutoFile dc2in(path, "rb");
AutoFile textout(path, "w");
and so on.

It's not clear to me what it does.

Whilst I understand
Code:
    AutoFile(FILE * file);
    AutoFile(const char * filename, const char * mode);
as two possible use:
Code:
Autofile(myfile);
or
Code:
Autofile(myfile, "rb");
How is it possible they use the
Code:
AutoFile dc2in(myfile, "rb");
syntax?
I see that the arguments are same for AutoFile and the second function next to it. But cannot find declaration or definition for that next functions. This use of arguments looks strange to me.
 

code65536

Golden Member
Mar 7, 2006
1,006
0
76
This use of arguments looks strange to me.

Are you required to use this? If not, then why are you using it? Don't use code that you don't understand, especially if it's something so trivial in the first place. I'm guessing from the name and the declaration that the only benefit to AutoFile is that it automatically closes the file handle when it falls out of scope (assuming you didn't use the new operator to create it), which means it basically does nothing useful. Especially when you are writing more complex code, it is simply better programming practice to do things like this explicitly instead of implicitly.

It's just a trivial wrapper around fopen; a totally unnecessary use of a class. So, again, unless you're required to use it, why not just directly call the thing that it's wrapping?

What do you mean? Do you want to say that I should use
string.h
instead
iostream
Programming is not about memorizing and chanting the right incantations. You must understand what you're chanting, especially with C/C++. Which is why I said earlier that it's stupid so many people who teach C/C++ dive right into the C++ without teaching the foundation C. Do you understand how strings are represented in the world of low-level programming like assembler and C? Once you understand that and how pointers work, it will become obvious what to do, and things will become so much, much easier.
 

h4ever

Member
Aug 30, 2013
163
0
0
I have read about pointers. I think you mean to learn not to teach.

I need to explain how to declare the function return type for char [MAX_PATH] ... I found that when I type

char [_MAX_PATH] Setts::GetTempFileName(char fileName [_MAX_PATH])
so it is incorrect syntax.

I could use char * Setts::GetTempFileName(char fileName [_MAX_PATH]) but this leads to the problem in assigning the result to variable which is char [_MAX_PATH] ...
 
Last edited: