简体   繁体   English

如何* char + * char in c++?

[英]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我会得到下一个 output: something

But I only have this:但我只有这个:

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

and I need to get the following output我需要得到以下 output

So, How do I do this?那么,我该怎么做呢? And yes, I really need char * exactly.是的,我真的需要char *

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 . 您需要创建大小为strlen(chr1) + strlen(chr2) + 1 + 1缓冲区(最后一个+1因为strlen返回没有空终止符的字符串长度,但是c字符串应以空终止符结尾),然后复制使用str(n)cpy在新缓冲区中的第一个字符串,然后使用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. 正如ScarletAmanranth已经提到的那样,即使strcat()可能是最好的解决方案,但还有另一种解决方案。

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. 也可以先将c字符串转换为std::string ,对它们执行任何所需的操作,然后将结果转换回c字符串。 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. 可以写为oneliner,而无需任何其他的缓冲区传递。
  • Might allow easier manipulation through std::string methods and related functions 可以通过std::string方法和相关函数更轻松地进行操作

Drawbacks: 缺点:

  • Additional overhead 额外的开销
  • Only a const char* can be acquired, if a char* is required one must copy the c-string again 仅可获取const char* ,如果需要char*则必须再次复制c字符串

Consider that the returned const char* directly points to the internal buffer of the std::string object. 考虑返回的const char*直接指向std::string对象的内部缓冲区。 Thus the pointer only remains valid as long as the std::string object does not run out-of-scope. 因此,只要std::string对象没有超出范围,指针就保持有效。 Therefor using this with a temporary like this const char* result = (std::string(str1) + str2).c_str(); 因此将其与类似const char* result = (std::string(str1) + str2).c_str();的临时const char* result = (std::string(str1) + str2).c_str();一起使用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. 在这种情况下,您需要使用strcat()
As pointed out in the comments, you'll need something like char[] as a buffer for the new string. 如注释中所指出的,您将需要像char[]这样的东西作为新字符串的缓冲区。

Since this is C++, there had to be someone suggesting what I'm about to suggest. 由于这是C ++,因此必须有人提出我要提出的建议。 Use stringstream . 使用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* . calloc(int size, sizeof([type]))调用分配了保留最终char*所需的所有内存。 Like this, you can put two chars together ina more C++ way. 这样,您可以用更多的C ++方式将两个字符组合在一起。 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. 但是,您想要做的更像是C,但是由于您使用的是C ++,因此您可能会尽可能多地使用C ++中的方法。

Several considerations: 几个注意事项:

  • First you should declare chr1 and chr2 as const char * , not char * because attempting to modify a string literal is undefined behaviour. 首先, 您应该将chr1chr2声明为const char * ,而不是char *因为尝试修改字符串文字是未定义的行为。
  • Second, operator + on pointers involves pointer arithmetics, char * is not special in this respect. 其次,指针上的运算operator +涉及指针算术, char *在这方面并不特殊。 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 : 现有答案使用普通的旧C函数(Paranaix'除外),但是如果您像std::cout这样使用字符串流,则在C ++中会更加惯用:

     #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对象,然后流插入该结果字符串):

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: 而且由于这是流的属性,而不是字符串的属性,因此您可以使用char*输入来完成它:

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; 注意,我为字符串文字添加了必需的 const you may remove it if and only if your C-strings are not initialised by string literals. 只有当您的C字符串不是由字符串文字初始化时,您才可以删除它。

Normally the answer would be "use std::string". 通常,答案是“使用std :: string”。

And yes, I really need char * exactly. 是的,我确实确实需要char *。

Not just printing, I need to get char * variable as result container, which I need for futherer usage. 不只是打印,我还需要获取char *变量作为结果容器,以供将来使用。

... 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:我分享我的代码,以便能够在另一个 auto* 中添加 'char*' 的文本,而无需通过字符串或 cstring 到 go:

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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