Concat string in C++(STL) - c++

i have code like this
string xml_path(conf("CONFIG"));
xml_path+=FILE_NAME;
Where,
conf function returns char * and FILE name is const char *
I want to combine it to one line like
xml_path(conf("CONFIG")).append(FILE_NAME)
how do i do it?
any suggestions ??

Question asked for one line:
string xml_path = string(conf("CONFIG")) + string(FILE_NAME);
(I assume xml_path is the name of the variable, and not some sort of call in a library I don't know about).

Alternatively, if you want to format variable of different type, use a ostringstream.
eg.
std::ostringstream oss;
int a = 2;
char *s = "sometext";
oss<<s<<a<<endl;
cout<<oss.str(); // will output "sometext2"

const char * f = "foo";
char * b = "bar";
string s = string( f ) + b;
Note that you cannot use append(-0 because neither of the strings invvolved is a std:;string. If you really want to append, it will have to be two-stage process:
string s ( f );
s.append( b );

string xml_path(conf("CONFIG"));
xml_path += string(FILE_NAME);
should do the trick.

Related

Add a Char array to a Char * variable in c++

I am makinga code to send a query for my SQLlite database, but I just can't find a way to add a variable to the Char * variable that is being used as the query. the query and the variable that I want to add are declared like this:
String p = "10004F1F7";
char *sql = "SELECT * from TABELTAGGEGEVENS WHERE ID =" + p;
the error i get is this: error: invalid user-defined conversion from 'Arp::BasicString' to 'char*' [-fpermissive]
many thanks.
This doesn't work because in C++ the '+' operator on char pointers doesn't concatenate the strings.
One solution would be to make the literal value a String as well:
String p = "10004F1F7";
String query = "SELECT * from TABELTAGGEGEVENS WHERE ID =";
You can then concatenate like this: + operator: p + operator
I don't know the particular library you appear to be working with (Arp::BasicString), so I don't know how you'd convert that into a char *.
With std::string you can simply call c_str on the result.
Another and probably better solution is to use formatters.
For reference see:
https://www.thecodingdelight.com/string-cplusplus/
How to concatenate two strings in C++?
https://learn.microsoft.com/en-gb/cpp/text/string-and-i-o-formatting-modern-cpp?view=vs-2019
String p = "10004F1F7";
char *sql = "SELECT * from TABELTAGGEGEVENS WHERE ID =" + p;
You can handle the Arp::BasicString almost like an std::string.
Looking through the headers you will find a Method named "CStr()".
Like that you should be able to do something like this:
String P = "10004F1F7";
String Query = "SELECT * from TABELTAGGEGEVENS WHERE ID =" + p;
char *sql = Query.CStr()
The only hit on Google for Arp::BasicString was used in the SDK for a software company, PLCnext. A little bit of riffling through I found a header file BasicString.hxx and inside a prototype for BasicString class template. There the baseString data structure is private.
I had to come up with this (rather low-level) workaround, compiling with PLCnext software succeeded and passed tests when adjusted for std::string):
String p = "10004F1F7";
const char* CMD_SEQUENCE = "SELECT * from TABELTAGGEGEVENS WHERE ID =";
const int CMD_LENGTH = 41;
// allocate and assign memory for the static characters in the command
char *sql = (char *)malloc(CMD_LENGTH * sizeof(char));
memcpy(sql, CMD_SEQUENCE, CMD_LENGTH);
// iterate through all chars in String p
// resizing the memory buffer as needed and adding ith char to the end
for (int i=0; i<p.Size();i++){
sql = (char*)realloc(sql, (CMD_LENGTH + i) * sizeof(char));
// destination is the ith memory cell past the cmd sequence
int destIdx = CMD_LENGTH + i;
// copy 1 char at a time; ith char in p
memcpy( &sql[destIdx], &p.At(i), sizeof(char) );
}

Concatenating strings together in Arduino

I want to do something similar to this:
char* a = (char*)msg[0];
char* b = (char*)msg[1];
char* c = a + "," + b;
Where msg is an array of int.
N.B.: This is Arduino C++, not regular C++.
Arduino doesn't use std::string, instead it uses String (note the capital S and dropped std::). They're used the same way as std::string for the most part. So basically you should just be able to do this:
String a("hello");
String b(" world");
c = a + b;
If you want to convert an integer to a String, it has a constructor to do just that, e.g.:
String a = String(msg[0]);
String b = String(msg[1]);
You can find more examples here and here.
See strcat.
You seem to be programming C, not C++.
This should be covered in the most basic tutorials.
SOLUTION
so here is my solution thank everyone.
String a = String(msg[0]);
String b = String(msg[1]);
String c = a + "," + b;
char* d;
c.toCharArray(d,c.length());
mclient.publish("topic1/sensorAck",d);

How do i combine character arrays char *foo = (char *bar1 + char *bar2 + char *bar3)

I have two prefilled arrays as follows:
char *query1;
char *query2;
and one array that is filled by the user.
char *username;
what i want to do is combine these into one for example
char *SQLquery;
i have try'd working with strlen and strcat in this way:
if (query==3) {
char *query1 = "SELECT * FROM Users WHERE UserName='";
char *username = "DEFSER"; //prefilled this for test purpuse
char *query2 = "'";
SQLquery = new char[strlen(query1)+strlen(username)+strlen(query2)+1];
*SQLquery = '/0';
strcat(SQLquery,query1);
strcat(SQLquery,username);
strcat(SQLquery,query2);
strcpy(laArray[0][2],SQLquery);
}
there is no compiler error however when i print my laArray[0][2] or my SQLquery it returns 0.
did i do something wrong?
If you plan to use C, use the following
const char query1[] = "SELECT * FROM Users WHERE UserName='";
char *username = "DEFSER";
SQLquery = malloc(strlen(query1) + strlen(username) + strlen(query2) + 1 + 1);
sprintf("%s%s'", query1, username);
laArray[0][2] = SQLquery; /* Based on comments, I believe this is what you want to do */
...
/* Do whatever you want to do with laArray */
...
laArray[0][2] = NULL;
free(SQLquery);
SQLquery = NULL;
If you plan to use C++, use the std::string like following
std::string SQLquery = "SELECT * FROM Users WHERE UserName='";
std::string username = "DEFSER";
SQLquery += username;
SQLquery += '\'';
laArray[0][2] = SQLquery; /* if laArray is 2D array of string, const_cast<char *>(SQLquery.c_str()) if it contains pointers */
/* Do whatever you want to do with laArray */
...
I understand BLUEPIXY has already spotted the real issue, but just to add another option, you could use sprintf_s(...) to do your string concatenation and potentially provide some more control over formatting (should that be required).
For the suggestions of using std::string (if in C++): you'll need to use the c_str() method to access the char* from std::string if you need to convert back to a old-style C char string.
Good luck.
It is impossible to use direct '+' concatenation in C. In C++ you could overload an operator, but it would be much smarter to use std::string, which already overloads the operator+ and then extract c_str() out of it to get const char *.

Converting Zero-Terminated String To D String

Is there a function in Phobos for converting a zero-terminated string into a D-string?
So far I've only found the reverse case toStringz.
I need this in the following snippet
// Lookup user name from user id
passwd pw;
passwd* pw_ret;
immutable size_t bufsize = 16384;
char* buf = cast(char*)core.stdc.stdlib.malloc(bufsize);
getpwuid_r(stat.st_uid, &pw, buf, bufsize, &pw_ret);
if (pw_ret != null) {
// TODO: The following loop maybe can be replace by some Phobos function?
size_t n = 0;
string name;
while (pw.pw_name[n] != 0) {
name ~= pw.pw_name[n];
n++;
}
writeln(name);
}
core.stdc.stdlib.free(buf);
which I use to lookup the username from a user id.
I assume UTF-8 compatiblity for now.
There's two easy ways to do it: slice or std.conv.to:
const(char)* foo = c_function();
string s = to!string(foo); // done!
Or you can slice it if you are going to use it temporarily or otherwise know it won't be written to or freed elsewhere:
immutable(char)* foo = c_functon();
string s = foo[0 .. strlen(foo)]; // make sure foo doesn't get freed while you're still using it
If you think it can be freed, you can also copy it by slicing then duping: foo[0..strlen(foo)].dup;
Slicing pointers works the same way in all array cases, not just strings:
int* foo = get_c_array(&c_array_length); // assume this returns the length in a param
int[] foo_a = foo[0 .. c_array_length]; // because you need length to slice
Just slice the original string (no coping). The $ inside [] is translated to str.length. If the zero is not at the end, just replace the "$ - 1" expression with position.
void main() {
auto str = "abc\0";
str.trimLastZero();
write(str);
}
void trimLastZero (ref string str) {
if (str[$ - 1] == 0)
str = str[0 .. $ - 1];
}
You can do the following to strip away the trailing zeros and convert it to a string:
char[256] name;
getNameFromCFunction(name.ptr, 256);
string s = to!string(cast(char*)name); //<-- this is the important bit
If you just pass in name you will convert it to a string but the trailing zeroes will still be there. So you cast it to a char pointer and voila std.conv.to will convert whatever it meets until a '\0' is encountered.

C++ std::string length() or size() not working on method args

I have a method that that creates a MatLab array name from a file path and returns it as a std::string. the resulting string is passed into another method that writes the name to the file. When I try to get the length of the passed in string, it displays 0 when the length of the string is 12 or 13 chars.
My code:
bool MyClass::masterMethod(std::string fileURI){
FILE* dataStream;
// Assume dataStream is set up correctly
// Get arrayName from File URI
std::string arrayName = this->makeArrayNameFromPath( fileURI);
//Write array name to file
this->writeArrayName(arrayName , dataStream)
}
std::string MyClass::makeArrayNameFromPath(std::string filePathURI){
std::string tempString = filePathURI.substr(filePathURI.find_last_of('/')+1);
std::string returnString = "";
long index = 0;
for(long i = 0; i < tempString.length(); i++){
if((tempString[i] != ' ') && (tempString[i] != '.')){
returnString[index++] = tempString[i];
}
}
return returnString;
}
void MyClass::writeArrayName(std::string name , FILE *nameStream){
// long testLength = name.length();
// long testLength2 = name.size();
// const char* testChar = nam.c_str();
// long testCharLen = strlen(testChar);
// The size of the name is the number of Chars * sizeof(int8_t)
int32_t sizeOfName = (int32_t)(name.length() * sizeof(int8_t));
int32_t nameType = miINT8;
fwrite(&nameType , sizeof(int32_t) , 1 , nameStream);
fwrite(&sizeOfName, sizeof(sizeOfName), 1, nameStream);
fwrite(&name , sizeof(name[0]), sizeOfName , nameStream);
}
So I'm not sure why string::length is not working. If a create a std::string test = name, and print it , I can get the value of the string but can not get its length or size.
If I use const char* testName = name.c_str(); long test = strlen(testName), I get a the
correct value, but thought that wasn't necessary.
So any advice or suggestion is appreciated.
returnString[index++] = tempString[i]; doesn't do what you think it does. It's not adding additional space or length to the string, only overwriting memory at a location that the string doesn't actually own. I think returnString.append(1, tempString[i]) or similar should do it.
You never give the string a size, just trying to assign positions that isn't there.
Try this instead to add characters to the return value
returnString += tempString[i];