The*_*i.9 324 c string concatenation
我在C工作,我必须连接一些东西.
现在我有这个:
message = strcat("TEXT ", var);
message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));
Run Code Online (Sandbox Code Playgroud)
现在,如果您有C语言经验,我确信您在尝试运行时会发现这会给您带来分段错误.那我该如何解决呢?
Bri*_*ndy 359
在C中,"字符串"只是普通char
数组.因此,您无法直接将它们与其他"字符串"连接起来.
您可以使用该strcat
函数,该函数将指向的字符串附加到指向的字符串src
的末尾dest
:
char *strcat(char *dest, const char *src);
Run Code Online (Sandbox Code Playgroud)
以下是cplusplus.com的示例:
char str[80];
strcpy(str, "these ");
strcat(str, "strings ");
strcat(str, "are ");
strcat(str, "concatenated.");
Run Code Online (Sandbox Code Playgroud)
对于第一个参数,您需要提供目标缓冲区本身.目标缓冲区必须是char数组缓冲区.例如:char buffer[1024];
确保第一个参数有足够的空间来存储您尝试复制到其中的内容.如果您可以使用,则使用以下函数会更安全:strcpy_s
并且strcat_s
您必须明确指定目标缓冲区的大小.
注意:字符串文字不能用作缓冲区,因为它是常量.因此,您始终必须为缓冲区分配char数组.
strcat
可以简单地忽略返回值,它只返回与第一个参数传入的指针相同的指针.它是为了方便,允许您将调用链接到一行代码:
strcat(strcat(str, foo), bar);
Run Code Online (Sandbox Code Playgroud)
所以你的问题可以解决如下:
char *foo = "foo";
char *bar = "bar";
char str[80];
strcpy(str, "TEXT ");
strcat(str, foo);
strcat(str, bar);
Run Code Online (Sandbox Code Playgroud)
Ale*_*x B 237
避免strcat
在C代码中使用.最干净,最重要的是,最安全的方法是使用snprintf
:
char buf[256];
snprintf(buf, sizeof buf, "%s%s%s%s", str1, str2, str3, str4);
Run Code Online (Sandbox Code Playgroud)
一些评论者提出了一个问题,即参数的数量可能与格式字符串不匹配,代码仍然会编译,但大多数编译器已经发出警告,如果是这种情况.
Mr.*_*Ree 24
伙计们,使用str n cpy(),str n cat()或s n printf().
超过你的缓冲空间会破坏内存中的其他内容!
(并且记得为尾随的空'\ 0'字符留出空间!)
小智 17
字符串也可以在编译时连接.
#define SCHEMA "test"
#define TABLE "data"
const char *table = SCHEMA "." TABLE ; // note no + or . or anything
const char *qry = // include comments in a string
" SELECT * " // get all fields
" FROM " SCHEMA "." TABLE /* the table */
" WHERE x = 1 " /* the filter */
;
Run Code Online (Sandbox Code Playgroud)
Ree*_*ges 16
如果您事先不知道连接多少个字符串,malloc和realloc也很有用.
#include <stdio.h>
#include <string.h>
void example(const char *header, const char **words, size_t num_words)
{
size_t message_len = strlen(header) + 1; /* + 1 for terminating NULL */
char *message = (char*) malloc(message_len);
strncat(message, header, message_len);
for(int i = 0; i < num_words; ++i)
{
message_len += 1 + strlen(words[i]); /* 1 + for separator ';' */
message = (char*) realloc(message, message_len);
strncat(strncat(message, ";", message_len), words[i], message_len);
}
puts(message);
free(message);
}
Run Code Online (Sandbox Code Playgroud)
尝试修改字符串文字是未定义的行为,类似于:
strcat ("Hello, ", name);
Run Code Online (Sandbox Code Playgroud)
会尝试做。它将尝试name
将字符串附加到字符串文字的末尾"Hello, "
,这不是很好的定义。
试试这个。它实现了您似乎想要做的事情:
char message[1000];
strcpy (message, "TEXT ");
strcat (message, var);
Run Code Online (Sandbox Code Playgroud)
这将创建一个缓冲区域被允许修改,然后拷贝这两个字符串文字等文本。小心缓冲区溢出。如果您控制输入数据(或事先检查它),则可以像我一样使用固定长度的缓冲区。
否则,您应该使用缓解策略,例如从堆中分配足够的内存以确保您可以处理它。换句话说,类似于:
const static char TEXT[] = "TEXT ";
// Make *sure* you have enough space.
char *message = malloc (sizeof(TEXT) + strlen(var) + 1);
if (message == NULL)
handleOutOfMemoryIntelligently();
strcpy (message, TEXT);
strcat (message, var);
// Need to free message at some point after you're done with it.
Run Code Online (Sandbox Code Playgroud)
小智 5
如果您有 C 方面的经验,您会注意到字符串只是最后一个字符是空字符的 char 数组。
现在这很不方便,因为您必须找到最后一个字符才能附加某些内容。strcat
会为你做的。
所以 strcat 在第一个参数中搜索空字符。然后它将用第二个参数的内容替换它(直到它以空值结尾)。
现在让我们来看看你的代码:
message = strcat("TEXT " + var);
Run Code Online (Sandbox Code Playgroud)
在这里,您向指向文本“TEXT”的指针添加了一些内容(“TEXT”的类型是 const char*。一个指针。)。
那通常是行不通的。修改“TEXT”数组也不起作用,因为它通常放在一个常量段中。
message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));
Run Code Online (Sandbox Code Playgroud)
这可能会更好,除非您再次尝试修改静态文本。strcat 没有为结果分配新的内存。
我建议做这样的事情:
sprintf(message2, "TEXT %s TEXT %s", foo, bar);
Run Code Online (Sandbox Code Playgroud)
阅读文档sprintf
以检查它的选项。
现在重要的一点:
确保缓冲区有足够的空间来容纳文本和空字符。有几个函数可以帮助您,例如 strncat 和特殊版本的 printf 为您分配缓冲区。不确保缓冲区大小将导致内存损坏和可远程利用的错误。
不要忘记初始化输出缓冲区.strcat的第一个参数必须是以空字符结尾的字符串,并为结果字符串分配足够的额外空间:
char out[1024] = ""; // must be initialized
strcat( out, null_terminated_string );
// null_terminated_string has less than 1023 chars
Run Code Online (Sandbox Code Playgroud)
正如人们指出的那样,字符串处理有了很大改进。因此,您可能想学习如何使用 C++ 字符串库而不是 C 样式字符串。然而这里有一个纯C的解决方案
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void appendToHello(const char *s) {
const char *const hello = "hello ";
const size_t sLength = strlen(s);
const size_t helloLength = strlen(hello);
const size_t totalLength = sLength + helloLength;
char *const strBuf = malloc(totalLength + 1);
if (strBuf == NULL) {
fprintf(stderr, "malloc failed\n");
exit(EXIT_FAILURE);
}
strcpy(strBuf, hello);
strcpy(strBuf + helloLength, s);
puts(strBuf);
free(strBuf);
}
int main (void) {
appendToHello("blah blah");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我不确定它是否正确/安全,但现在我找不到更好的方法在 ANSI C 中执行此操作。
没有限制缓冲区大小的最佳方法是使用 asprintf()
char* concat(const char* str1, const char* str2)
{
char* result;
asprintf(&result, "%s%s", str1, str2);
return result;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
986117 次 |
最近记录: |