gpt4 book ai didi

c - 在c中连接字符串的最有效方法

转载 作者:太空宇宙 更新时间:2023-11-04 06:12:58 25 4
gpt4 key购买 nike

考虑这个连接所有指定参数并在标准输出中打印它们的简单程序。我使用了 2 个 for 循环来附加字符串,一个用于计算该字符串的长度,一个用于连接字符串。有没有一种方法只用一个循环就可以做到这一点?为每个要连接的字符串重新分配内存不会更有效,不是吗? Java 的 StringBuilder 在 C 中如何实现?它会像我一样循环两次吗?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
size_t len = 0;

// start for loop at i = 1 to skip the program name specified in argv
for(int i = 1; i < argc; i++)
len += strlen(argv[i]) + 1; // +1 for the space

char* toAppend = (char*)malloc(len * sizeof(char) + 1);
toAppend[0] = '\0'; // first string is empty and null terminated

for(int i = 1; i < argc; i++)
{
strcat(toAppend, argv[i]);
strcat(toAppend, " ");
}

printf(toAppend);
free(toAppend);
}

最佳答案

您的分配方法很有效,测量总长度并只分配一次。但是连接循环从一开始就重复测量输出缓冲区的长度以连接到它,导致二次运行时间。

要修复它,请在您前进时跟踪您的位置:

size_t pos = 0;
for(int i = 1; i < argc; i++) {
size_t len = strlen(argv[i]);
memcpy(toAppend+pos, argv[i], len);
pos += len;
toAppend[pos] = ' ';
pos++;
}
toAppend[pos] = 0;

这是在内存中实际连接的最有效方法,但最有效的方法是不连接。相反:

for(int i = 1; i < argc; i++)
printf("%s ", argv[i]);

缓冲 stdio 的全部原因是您不必构建任意长度的内存缓冲区来进行高效输出;相反,它会自动缓冲到固定大小,并在缓冲区已满时刷新。

请注意,如果您的输入在任何地方包含 % 字符,您对 printf 的使用是错误和危险的;它应该是 printf("%s", toAppend);

如果您正在编写 POSIX(或 POSIX-ish)系统而不仅仅是普通的 C,另一个选项是 fmemopen,它允许您像这样编写循环:

for(int i = 1; i < argc; i++)
fprintf(my_memfile, "%s ", argv[i]);

关于c - 在c中连接字符串的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52415807/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com