How to concatenate string in ROOT,c++? - c++

I want to concatenate two string and I did in my program like String Filename = name+ "" + extension where extension is an integer value that I read just above this line and name is the path that is already defined.
But in ROOT I am getting error like Error: + illegal operator for pointer 1
What went wrong here? Is there any other method?

If extension is an integer, then convert it to a string first.
std::string Filename = name+ "" + std::to_string(extension);
+""+ does nothing, btw

The TString class in ROOT has a function called "Format" which you can use to concatenate strings the same way you format a print statement. Here is the documentation for the Format method: https://root.cern.ch/root/html/TString.html#TString:Format
and here is the documentation for how the formatting works http://www.cplusplus.com/reference/cstdio/printf/

I'm going to go ahead and assume the 'name' is a char*.
Char const* name = "john";
Char const* space = " ";
Here name and space are 2 pointers to character arrays.
When you add try to add these 2 together, the compiler tries to add the value of the 2 pointer together. This makes no sense to the compiler. You can obviously only add an offset to a pointer.
The solution to this is to make sure that one of the 2 things you are adding is a std::string and not 'c string'.

Related

C++ SNAP Library convert std::string to TStr

In the SNAP Library there's a method that allows me to save a file in my pc here it is:
TSnap::SaveEdgeList(G, q, "Edge list format");`
in this function the 2nd argument its type is TStr which represents string types in SNAP library
I have a string variable that contains a full directory of where I want to put my file like this:
string filedir = openFileDialog1->FileName;
What I want to do is to give the content of a string variable to a TStr variable like this:
TStr q = filedir;
But unfortunately it gives an error.
So i was wondering if anyone has an alternative solution or something Thank you
Quick googling revealed that TStr can be constructed from a C-string via TStr(const char* CStr) constructor.
So, following will work:
TStr q = filedir.c_str();
Alternatively, you can pass filedir.c_str() directly as an argument.

getenv in C++ returns wrong values

I would like to write my program in 2 different paths. So, I proceeded like that :
std::string path1 = strcat(std::getenv("APPDATA"),"\\myprog.exe") ;
std::string path2 = strcat(std::getenv("APPDATA"),"\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\myprog.exe") ;
When I print, I get :
C:\Users\thispc\AppData\Roaming\myprog.exe
C:\Users\thispc\AppData\Roaming\myprog.exe\Microsoft\Windows\Start Menu\Programs\Startup\myprog.exe
instead of :
C:\Users\thispc\AppData\Roaming\myprog.exe
C:\Users\thispc\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\myprog.exe
Solution by Dietmar Kühl :
std::string path1 = std::getenv("APPDATA") + std::string("\\myprog.exe");
Explanation by Oliver Charlesworth :
strcat() changes the 1st variable
What is happening here is that std::getenv("APPDATA") gives you a pointer to a already written string somewhere in memory, that means the pointer returned by this function will always be the same.
Thus when you do strcat(std::getenv("APPDATA"),"\\myprog.exe") you basically concatenate that stored string in memory with "\\myprog.exe". So when you make a second call of std::getenv("APPDATA") you will get the concatenated string.
To solve this problem you should copy the string at std::getenv("APPDATA")

How to append to a string without changing original value when passing as a parameter?

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"));
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.
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
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.
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());

how can i add this variable to my path for ifstream?

I'm trying to append my path and contain a variable as part of the path but I'm getting an error.
What's wrong with it?
fstream fin("E:\\Games\\maps\\" + this->MapNumber + ".map", ios::in|ios::binary|ios::ate);
this->MapNumber is a USHORT
error: 13 IntelliSense: expression must have integral or unscoped enum type
In C++ you can't use + to concatenate literal strings. You can use + with std::strings to concatenate them, but that won't work with integer or other types. You need to use a stream instead. Insertion and extraction into a stream will cause the types that support it to represent themselves as text, but you probably already knew this from general I/O.
Try with something like this:
std::stringstream filename;
filename << "E:\\Games\\maps\\" << this->MapNumber << ".map";
std::fstream fin(filename.str().c_str(), ios::in|ios::binary|ios::ate);
Just like with everything else, to use something you need to include the header that declares it first. In order to use std::stringstream you need to include <sstream>.
You can't use operator+ on a string and another type like string or so you can either:
Option1: turn all variables into strings to append them
string s = string("E:\\Games\\maps\\") + string(itoa(this->MapNumber)) + string(".map");
option2: use stringstream as #k-ballo explained
option3: use the good old C fprintf (my personal favourite)
char str[100];
fprintf(str, "E:\\Games\\maps\\ %d .map", this->MapNumber);

How to use string and string pointers in C++

I am very confused about when to use string (char) and when to use string pointers (char pointers) in C++. Here are two questions I'm having.
which one of the following two is correct?
string subString;
subString = anotherString.sub(9);
string *subString;
subString = &anotherString.sub(9);
which one of the following two is correct?
char doubleQuote = aString[9];
if (doubleQuote == "\"") {...}
char *doubleQuote = &aString[9];
if (doubleQuote == "\"") {...}
None of them are correct.
The member function sub does not exist for string, unless you are using another string class that is not std::string.
The second one of the first question subString = &anotherString.sub(9); is not safe, as you're storing the address of a temporary. It is also wrong as anotherString is a pointer to a string object. To call the sub member function, you need to write anotherString->sub(9). And again, member function sub does not exist.
The first one of the second question is more correct than the second one; all you need to do is replace "\"" with '\"'.
The second one of the second question is wrong, as:
doubleQuote does not refer to the 10th character, but the string from the 10th character onwards
doubleQuote == "\"" may be type-wise correct, but it doesn't compare equality of the two strings; it checks if they are pointing to the same thing. If you want to check the equality of the two strings, use strcmp.
In C++, you can (and should) always use std::string (while remembering that string literals actually are zero-terminated character arrays). Use char* only when you need to interface with C code.
C-style strings need error-prone manual memory management, need to explicitly copy strings (copying pointers doesn't copy the string), and you need to pay attention to details like allocating enough memory to have the terminating '\0' fit in, while std::string takes care of all this automagically.
For the first question, the first sample, assuming sub will return a substring of the provided string.
For the second, none:
char doubleQuote = aString[9];
if( doubleQuote == '\"') { ... }
Erm, are you using string from STL?
(i.e. you have something like
#include <string>
#using namespace std;
in the beginning of your source file ;) )
then it would be like
string mystring("whatever:\"\""");
char anElem = mystring[9];
if (anElem=="\"") { do_something();}
or you can write
mystring.at(9)
instead of square brackets.
May be these examples can help.