I have two LPCSTRs I need to concatenate like so:
if (!rename(directory + originalFileName, directory + fileName)){
std::cout<<originalFileName<<std::endl<<fileName<<std::endl<<std::endl;
}
The only problem however is that I can't use the + operator here. How can I safely concatenate two LPCSTRs like this?
EDIT: Note that an LPCSTR is defined as a const * char while an LPCTSTR is defined as const TCHAR*. The two are different when UNICODE and/or _UNICODE are defined. In this case, they are.
Since LPCSTR is a CONST CHAR* i used this,
(string(dir) + string(originalFileName)).c_str()
Since these strings are const you will need a new buffer to hold the results. That means finding the length of the strings with 'strlen', allocating a buffer with 'new', and copying the strings with 'strcpy' and 'strcat'
That's a hint for how to learn it, instead of me writing the code for you.
Also, there are other options such as using std::string or CString depending on your toolset.
Thanks to WhozCraig, I got the answer:
LPCSTR str1 = "foo",
str2 = "bar";
std::string(str1).append(str2).c_str();
std::cout<<str1;
Returns
foobar
You may use the std::string class to do the heavy lifting because it contains overloaded operator+. However you must ensure that the std::string object is not destroyed before you attempt to read its contents.
One way (in C++03) would be:
std::string dest = std::string(directory) + originalFileName;
std::string src = std::string(directory) + fileName;
if (!rename(dest.c_str(), src.c_str())
// whatever...
Consider storing directory as a std::string in the first place.
Related
I do have this function defined in windows playsoundapi.h.
PlaySound(L"D:\\resources\\English\\A.wav", NULL, SND_LOOP);
I want to concatenate a variable to replace "A.wav" in c++.
The variable is of type char*
Can anyone suggest a solution to this please? Much appreciated.
In C++17 or above use std::filesystem::path which is more handy for such scenario:
using std::filesystem::path;
path file = ...; // L"A.wav" // here can be wide characters things and regular character things - proper conversion is done implicitly
path base{L"D:\\resources\\English"};
PlaySound((base / file).c_str(), NULL, SND_LOOP);
Note that std::filesystem::path::c_str() returns const wchar_t* on Windows and const char * on other platforms.
Return value
The native string representation of the pathname, using native syntax, native character type, and native character encoding. This string is suitable for use with OS APIs.
Simple enough
std::wstring var = ...;
PlaySound((L"D:\\resources\\English\\" + var).c_str(), NULL, SND_LOOP);
But if your variable is something other than a std::wstring, then that is a different question. Please add more details if that is the case.
EDIT
It seems the variable is type char*. One possible solution is to make a std::wstring variable from the char* variable
char* var = ...;
std::wstring tmp(var, var + strlen(var));
PlaySound((L"D:\\resources\\English\\" + tmp).c_str(), NULL, SND_LOOP);
This does assume that there are no encoding issues in copying from char to wchar_t but again that's a detail not provided in the question.
Also you should consider why the variable is char* in the first place. You are working with an API that requires wide characters, so why not use wide characters in your code?
Assign your char* string to a std::string, which you can then concatenate with your base path, and then use the std::string::c_str() method to get a const char* pointer that you can pass to PlaySound(), eg:
std::string fileName = "A.wav";
PlaySoundA(("D:\\resources\\English\\" + fileName).c_str(), NULL, SND_LOOP);
well I'm going to be brief here.
I have this variable:
char* String;
and a function:
void AddString(char str[])
{
}
And I need to add the str to String at the end of it for example:
if String = "ABC"
and str = "123"
after the function AddString String = "ABC123"
I searched all over the web, but I couldn't find what I need, any help?
In C++, use std::string rather than C-style character arrays:
#include <string>
std::string String;
void AddString(std::string str) {
String += str;
}
If you really want to do that by steam, then you'll need to allocate a large enough array for the result, copy the strings in, and remember to put a terminator (zero-valued character) after the end. C library functions like strlen, strcpy and strcat might be useful. The details are left as an exercise, since the question is about C++ not C.
For using C strings you have functions inside the cstring header file. To concatenate strings you have strcat
use strcat to combine the two char*
strcat takes two parameters, the destination char array c1 and the source char array c2.
You need to be sure that c1 is big enough to hold all the char from c1 and c2.
However you could use c++ strings. and the + operator will handle this for you.
string s1, s2;
string s3 = s1+s2
char* String;
void AddString(char str[])
{
strcat(String , str);
}
/*Also, make sure you have allocated space for String before using AddString*/
String = malloc(25*sizeof(char)); //25 just an example.
Also, since this is tagged for C++
You should be using std::string instead as shown in other answers
I get this error quite often when I try to do something like this
CString filePath = theApp->GetSystemPath() + "test.bmp";
The compiler tells me
error C2110: '+' : cannot add two pointers
But if I change it to this below it works fine?
CString filePath = theApp->GetSystemPath();
filePath += "test.bmp";
The function GetSystemPath returns a LPCTSTR if that has anything to do with it
This has to do with the types of objects that you are dealing with.
CString filePath = theApp->GetSystemPath() + "test.bmp";
The line above is attempting to add the type of GetSystemPath() with "test.bmp" or an LPCTSTR + char[]; The compiler does not know how to do this because their is no + operator for these two types.
The reason this works:
filePath += "test.bmp";
Is because you are doing CString + char[] (char*); The CString class has the + operator overloaded to support adding CString + char*. Or alternatively which is constructing a CString from a char* prior to applying the addition operator on two CString objects. LPCTSTR does not have this operator overloaded or the proper constructors defined.
Well you can't add two pointers. The reason filePath += "test.bmp"; works is that the left hand side is a CString not a pointer. This would also work
CString(theApp->GetSystemPath()) + "test.bmp";
and so would this
theApp->GetSystemPath() + CString("test.bmp");
The rules of C++ prevent you overloading operators unless at least one of the argument is of class type. So it's not possible for anyone to overload operator+ for pointers only.
When doing this:
CString filePath = theApp->GetSystemPath() + "test.bmp";
You are trying to sum two pointers of type const char*. As the compiler is telling you, there is no overload of operator + that accepts two pointers of type const char*s as its input (after all, what you want is not to sum the pointers, but to concatenate the zero-terminated strings pointed to by those pointers).
On the other hand, there is an overload of operator += (as well as of operator +) that takes a CString and a const char*, which is why the second example compiles. For the same reason, this would also work:
CString filePath = theApp->GetSystemPath() + CString("test.bmp");
As well as this:
CString filePath = CString(theApp->GetSystemPath()) + "test.bmp";
The compiler may not be aware that the programmer is intending to concatenate two strings. it merely sees that a char const * is being added with another using the + operator.
I'd try something like this:
CString filePath = CString( theApp->GetSystemPath() ) + CString( "test.bmp" );
I have done a search in google and been told this is impossible as I can only get a static char * from a string, so I am looking for an alternative.
Here is the situation:
I have a .txt file that contains a list of other .txt files and some numbers, this is done so the program can be added to without recompilation. I use an ifstream to read the filenames into a string.
The function that they are required for is expecting a char * not a string and apparently this conversion is impossible.
I have access to this function but it calls another function with the char * so I think im stuck using a char *.
Does anyone know of a work around or another way of doing this?
In C++, I’d always do the following if a non-const char* is needed:
std::vector<char> buffer(str.length() + 1, '\0');
std::copy(str.begin(), str.end(), buffer.begin());
char* cstr = &buffer[0];
The first line creates a modifiable copy of our string that is guaranteed to reside in a contiguous memory block. The second line gets a pointer to the beginning of this buffer. Notice that the vector is one element bigger than the string to accomodate a null termination.
You can get a const char* to the string using c_str:
std::string str = "foo bar" ;
const char *ptr = str.c_str() ;
If you need just a char* you have to make a copy, e.g. doing:
char *cpy = new char[str.size()+1] ;
strcpy(cpy, str.c_str());
As previous posters have mentioned if the called function does in fact modify the string then you will need to copy it. However for future reference if you are simply dealing with an old c-style function that takes a char* but doesn't actually modfiy the argument, you can const-cast the result of the c_str() call.
void oldFn(char *c) { // doesn't modify c }
std::string tStr("asdf");
oldFn(const_cast< char* >(tStr.c_str());
There is c_str(); if you need a C compatible version of a std::string. See http://www.cppreference.com/wiki/string/basic_string/c_str
It's not static though but const. If your other function requires char* (without const) you can either cast away the constness (WARNING! Make sure the function doesn't modify the string) or create a local copy as codebolt suggested. Don't forget to delete the copy afterwards!
Can't you just pass the string as such to your function that takes a char*:
func(&string[0]);
I'm trying to make changes to some legacy code. I need to fill a char[] ext with a file extension gotten using filename.Right(3). Problem is that I don't know how to convert from a CStringT to a char[].
There has to be a really easy solution that I'm just not realizing...
TIA.
If you have access to ATL, which I imagine you do if you're using CString, then you can look into the ATL conversion classes like CT2CA.
CString fileExt = _T ("txt");
CT2CA fileExtA (fileExt);
If a conversion needs to be performed (as when compiling for Unicode), then CT2CA allocates some internal memory and performs the conversion, destroying the memory in its destructor. If compiling for ANSI, no conversion needs to be performed, so it just hangs on to a pointer to the original string. It also provides an implicit conversion to const char * so you can use it like any C-style string.
This makes conversions really easy, with the caveat that if you need to hang on to the string after the CT2CA goes out of scope, then you need to copy the string into a buffer under your control (not just store a pointer to it). Otherwise, the CT2CA cleans up the converted buffer and you have a dangling reference.
Well you can always do this even in unicode
char str[4];
strcpy( str, CStringA( cString.Right( 3 ) ).GetString() );
If you know you AREN'T using unicode then you could just do
char str[4];
strcpy( str, cString.Right( 3 ).GetString() );
All the original code block does is transfer the last 3 characters into a non unicode string (CStringA, CStringW is definitely unicode and CStringT depends on whether the UNICODE define is set) and then gets the string as a simple char string.
First use CStringA to make sure you're getting char and not wchar_t. Then just cast it to (const char *) to get a pointer to the string, and use strcpy or something similar to copy to your destination.
If you're completely sure that you'll always be copying 3 characters, you could just do it the simple way.
ext[0] = filename[filename.Length()-3];
ext[1] = filename[filename.Length()-2];
ext[2] = filename[filename.Length()-1];
ext[3] = 0;
I believe this is what you are looking for:
CString theString( "This is a test" );
char* mychar = new char[theString.GetLength()+1];
_tcscpy(mychar, theString);
If I remember my old school MS C++.
You do not specify where is the CStringT type from. It could be anything, including your own implementation of string handling class. Assuming it is CStringT from MFC/ATL library available in Visual C++, you have a few options:
It's not been said if you compile with or without Unicode, so presenting using TCHAR not char:
CStringT
<
TCHAR,
StrTraitMFC
<
TCHAR,
ChTraitsCRT<TCHAR>
>
> file(TEXT("test.txt"));
TCHAR* file1 = new TCHAR[file.GetLength() + 1];
_tcscpy(file1, file);
If you use CStringT specialised for ANSI string, then
std::string file1(CStringA(file));
char const* pfile = file1.c_str(); // to copy to char[] buffer