const char * конкатенация

<p>мне нужно объединить два константных символов, как эти:</p><pre><code>const char *one = "hello "; const char *two = "world"; </code></pre><p>как я могу сделать это?</p><p>я передал эти <code>char*</code> из сторонней библиотеки с интерфейсом c, поэтому я не могу просто использовать вместо этого <code>std::string</code>.</p>

<p>в вашем примере<em> one </em>и<em> two </em>являются указателями на символы, указывающими на константы типа char. вы не можете изменить константы типа char, на которые указывают эти указатели. так что-нибудь вроде:</p><pre><code>strcat(one,two); // append string two to string one. </code></pre><p>не будет работать. вместо этого у вас должна быть отдельная переменная (массив символов) для хранения результата. что-то вроде этого:</p><pre><code>char result[100]; // array to hold the result. strcpy(result,one); // copy string one into the result. strcat(result,two); // append string two to the result. </code></pre>

<p>c-путь:</p><pre><code>char buf[100]; strcpy(buf, one); strcat(buf, two); </code></pre><p>c++ способ:</p><pre><code>std::string buf(one); buf.append(two); </code></pre><p>способ компиляции:</p><pre><code>#define one "hello " #define two "world" #define concat(first, second) first second const char* buf = concat(one, two); </code></pre>

<p>если вы используете c++, почему бы вам не использовать <code>std::string</code> вместо строк в стиле c?</p><pre><code>std::string one="hello"; std::string two="world"; std::string three= one+two; </code></pre><p>если вам нужно передать эту строку в c-функцию, просто передайте <code>three.c\_str()</code></p>

<p>используя <code>std::string</code>:</p><pre><code>#include <string> std::string result = std::string(one) + std::string(two); </code></pre>

<p><strong> обновление: </strong>изменено <code>string total = string(one) + string(two);</code> to <code>string total( string(one) + two );</code> по соображениям производительности (избегает построения второй строки и итоговой временной строки)</p><pre><code>const char *one = "hello "; const char *two = "world"; string total( string(one) + two ); // or: string total = string(one) + string(two); // string total(move(move(string(one)) + two)); // even faster? // to use the concatenation in const char* use total.c\_str() </code></pre>

<p>еще один пример:</p><pre><code>// calculate the required buffer size (also accounting for the null terminator): int buffersize = strlen(one) + strlen(two) + 1; // allocate enough memory for the concatenated string: char* concatstring = new char[ buffersize ]; // copy strings one and two over to the new buffer: strcpy( concatstring, one ); strcat( concatstring, two ); ... // delete buffer: delete[] concatstring; </code></pre><p>но если вы специально не хотите или не можете использовать стандартную библиотеку c++, использование <code>std::string</code>, вероятно, более безопасно.</p>

<p>прежде всего, вы должны создать динамическое пространство памяти. тогда вы можете просто вставить две строки в него. или вы можете использовать c ++ "string" класс. старая школа c способом:</p><pre><code> char* catstring = malloc(strlen(one)+strlen(two)+1); strcpy(catstring, one); strcat(catstring, two); // use the string then delete it when you're done. free(catstring); </code></pre><p>новый способ c++</p><pre><code> std::string three(one); three += two; </code></pre>

<p>кажется, что вы используете c++ с библиотекой c, и поэтому вам нужно работать с <code>const char *</code>.</p><p>я предлагаю обернуть эти <code>const char *</code> в <code>std::string</code>:</p><pre><code>const char *a = "hello "; const char *b = "world"; std::string c = a; std::string d = b; cout << c + d; </code></pre>

<p>если вы не знаете размер строк, вы можете сделать что-то вроде этого:</p><pre><code>#include <stdio.h> #include <string.h> #include <stdlib.h> int main(){ const char* q1 = "first string"; const char* q2 = " second string"; char * qq = (char*) malloc((strlen(q1)+ strlen(q2))*sizeof(char)); strcpy(qq,q1); strcat(qq,q2); printf("%s\n",qq); return 0; } </code></pre>

<p>вы можете использовать <code>strstream</code>. это формально устарело, но это все еще отличный инструмент, если вам нужно работать со строками си, я думаю.</p><pre><code>char result[100]; // max size 100 std::ostrstream s(result, sizeof result - 1); s << one << two << std::ends; result[99] = '\0'; </code></pre><p>это запишет <code>one</code>, а затем <code>two</code> в поток и добавит завершающий <code>\0</code>, используя <code>std::ends</code>. в случае, если обе строки могут в конечном итоге написать ровно <code>99</code> символов - поэтому не останется места для записи <code>\0</code> - мы пишем одну вручную в последней позиции. </p>

<pre><code>const char* one = "one"; const char* two = "two"; char result[40]; sprintf(result, "%s%s", one, two); </code></pre>

<p>соединение двух константных указателей на символы без использования команды strcpy в динамическом распределении памяти:</p><pre><code>const char* one = "hello "; const char* two = "world!"; char* three = new char[strlen(one) + strlen(two) + 1] {'\0'}; strcat\_s(three, strlen(one) + 1, one); strcat\_s(three, strlen(one) + strlen(two) + 1, two); cout << three << endl; delete[] three; three = nullptr; </code></pre>