简体   繁体   中英

How to * char + * char in c++?

Here's a problem I've faced recently.

If I'll make something like this:

string str1 = "some";
string str2 = "thing";
cout << str1 + str2 << endl;

I'll get next output: something

But I only have this:

char *chr1 = "How do"
char *chr2 = "I do this?"

and I need to get the following output

So, How do I do this? And yes, I really need char * exactly.

You need to create buffer with size strlen(chr1) + strlen(chr2) + 1 + 1 , (last +1 since strlen returns length of string without null-terminator, but c-string should be ended with null-terminator) then copy first string in new buffer with str(n)cpy and then use str(n)cat .

char* buffer = new char[strlen(chr1) + strlen(chr2) + 1 + 1];
strcpy(buffer, chr1);
strcat(buffer, " ");
strcat(buffer, chr2);
// use buffer
delete[] buffer;

Even though strcat() is probably the best solution as already mentioned by ScarletAmanranth, there is also another one.

One can also convert the c-strings to std::string 's first, perform any desired operations on them and then convert the result back to a c-string. This might better suit your needs in some cases.

Example:

const char* str1 = "foo";
const char* str2 = "bar";

std::string combined = std::string(str1) + str2; // notice std::string + char* => std::string

const char* result = combined.c_str();

Advantages:

  • Can be written as oneliner, without any further delcarations of buffers etc.
  • Might allow easier manipulation through std::string methods and related functions

Drawbacks:

  • Additional overhead
  • Only a const char* can be acquired, if a char* is required one must copy the c-string again

Consider that the returned const char* directly points to the internal buffer of the std::string object. Thus the pointer only remains valid as long as the std::string object does not run out-of-scope. Therefor using this with a temporary like this const char* result = (std::string(str1) + str2).c_str(); is a very bad idea (whereas it would be legit to write someting like that in a function call, as the temporary remains until the call returns).

You need to use strcat() in such case.
As pointed out in the comments, you'll need something like char[] as a buffer for the new string.

Since this is C++, there had to be someone suggesting what I'm about to suggest. Use stringstream .

#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <string.h>

using namespace std;

int main() {
    char *chr1 = "How do";
    char *chr2 = "I do this?";
    stringstream ss;

    ss << chr1 << chr2;
    string result = ss.str();
    char* final = (char*) calloc(result.size()+1, sizeof(char));
    strcpy(final, result.c_str());

    cout << final << endl;

    delete [] chr1, chr2, final;

    return 0;
}

The calloc(int size, sizeof([type])) call alocates all the memory you need to keep your final char* . Like this, you can put two chars together ina more C++ way. However, what you're wanting to do is more like C, but since you're in C++, might as well use methods that are part of C++ as much as you can.

Several considerations:

  • First you should declare chr1 and chr2 as const char * , not char * because attempting to modify a string literal is undefined behaviour.
  • Second, operator + on pointers involves pointer arithmetics, char * is not special in this respect. If you need to concatenate strings, you need to allocate a buffer in which you copy the two strings one after the other.
  • Existing answers make use of plain old C functions (except Paranaix'), but it would be more idiomatic in C++ if you made a stringstream that you use like std::cout :

     #include <string> #include <stringstream> std::ostringstream ss; ss << chr1 << " " << chr2; const std::string s = ss.str(); const char *result = s.c_str(); // you can use this pointer during the scope of `s`. 

The string concatenation was not necessary in the first place; you can continue using the stream insertion operator << to perform effective concatenation (instead of using + to form one, temporary std::string object then stream-inserting that one resultant string):

std::string str1 = "some";
std::string str2 = "thing";
std::cout << str1 << str2 << std::endl;

And because this is a property of the stream and not the string, you can do it just as well with a char* input:

const char* chr1 = "How do "
const char* chr2 = "I do this?"
std::cout << chr1 << chr2 << std::endl;

// Output: How do I do this?

Notice that I added the required const for string literals; you may remove it if and only if your C-strings are not initialised by string literals.

Normally the answer would be "use std::string".

And yes, I really need char * exactly.

Not just printing, I need to get char * variable as result container, which I need for futherer usage.

... but in this case:

#include <cstring>

std::size_t len1 = std::strlen(str1);
std::size_t len2 = std::strlen(str2);
// unique_ptr: automated lifetime management
// 1 for '\0' terminator
std::unique_ptr<char[]> buffer( new char[len1 + len2 + 1] );
std::copy_n(str1, len1, buffer.get());
std::copy_n(str2, len2, buffer.get() + len1);
buffer.get()[len1 + len2] = '\0'; // after this, buffer.get()
                                  // points to your string

I share my code to be able to add the text of a 'char*' inside another auto* without the need to go through string or cstring:

#include <iostream>
using namespace std;

 int leng(char* tx){
     long long int n = 0;
     while(true){
         if(tx[n] == '\0'){
             break;
         }
         n += 1;
     }
         
     return n;
 }


int main(){
    char* t = "sffdsdssd";
    char* t2 = "axgdfb";
    long long int num = leng(t)+leng(t2);
    char g[num] = {0};
    long long int n = 0;
    for(n = 0; n < leng(t); n++){
        g[n] = t[n];
    }
    long long int num1 = leng(t);
    for(n = 0;  n < leng(t2); n++){
        g[num1+n] = t2[n];
    }
    char* resultado = (char*)g;
    cout << resultado;
    return 1;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM