所以我有一个循环,每次都会产生一个sting,我想把这个字符串附加到一个现有变量。
char fullString[] = "start: ";
while(x < 200){
char someVar[] = "test "
//append someVar to fullString
x++;
}
所以我想最终得到一个像这样的字符串:
start: test test test test test ...
我可以轻松地使用任何其他语言,只是不确定如何在c
中做任何想法?
答案 0 :(得分:5)
你应该有一个足够大的缓冲区来容纳整个连接字符串。
使用字符串函数strcat()
,如下所示
char fullString[2000] = "start: ";
while(x<200)
{
char someVar[] = "test "; // What ever valid string you want to append to the existing string
strcat(fullString,someVar);
x++;
}
答案 1 :(得分:2)
你可以这样使用,
char *full =malloc(10);// allocating the memory
if ( full == NULL ){
printf("allocation failed\n");
return;
}
strcpy(full,"Start: ");
char someVar[] ="test ";
char *temp;
while(x < 200 ) {
temp=realloc(full,(strlen(full)+1)+(strlen(someVar)+1));//reallocating for store repeatedly
if ( temp == NULL )
printf("allocation failed\n");
break;
}
full=temp;
strcat(full,someVar);
x++;
}
答案 2 :(得分:1)
今天早上我写了这个答案但是停电了。无论如何,无论如何都要引导提问者理解他。
在C中这并不容易,因为你必须自己管理字符串空间(其他语言也适合你)。
本质上,每次要追加到现有字符串时,都必须计算其当前长度,要追加的字符串的长度,分配新空间来保存两者,将现有部分复制到新的字符串内存,追加新字符串,并释放旧字符串。
有多种方法可以加快速度,例如使用realloc,正如其他人建议的那样,预先分配更大的缓冲区,跟踪当前的长度等等;但是,如果要附加可变长度字符串,则该方法不会更改。
答案 3 :(得分:1)
strcat(),malloc()和realloc()的成本经常被忽视。
我已经对这个案子玩了一些并得到了一些数字:
% ./catter "Start: " "test " 1000
realloc_catter: 379
prealloc_catter: 154
realloc_mycatter: 152
prealloc_mycatter: 8
% ./catter "Start: " "test " 100000
realloc_catter: 1453494
prealloc_catter: 741639
realloc_mycatter: 733160
prealloc_mycatter: 365
% ./catter "Start: " "test " 1000000
realloc_catter: 265374117
prealloc_catter: 128139699
realloc_mycatter: 127484834
prealloc_mycatter: 3397
这里我们清楚地看到O(n ^ 2)成本。适当优化的连接方法仅花费O(n)。
测试代码是:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
void measure(char *name, void (*func)(char**,char *,char*,int), char **target, char *initial, char *repeat, int times)
{
clock_t start, finish;
start = clock();
func(target, initial, repeat, times);
free(*target);
finish = clock();
printf("%20s: %10lld\n", name, (long long)(finish - start));
}
void realloc_catter(char **target, char *initial, char *repeat, int times)
{
*target = malloc(strlen(initial)+1);
strcpy(*target, initial);
for (int i = 0; i < times; i++) {
*target = realloc(*target, strlen(*target) + strlen(repeat) + 1);
strcat(*target, repeat);
}
}
void prealloc_catter(char **target, char *initial, char *repeat, int times)
{
*target = malloc(strlen(initial) + strlen(repeat) * times + 1);
strcpy(*target, initial);
for (int i = 0; i < times; i++) {
strcat(*target, repeat);
}
}
char *mystrcat(char *target, char *repeat)
{
for(;;) {
*target = *repeat;
if (!*repeat) break;
target++;
repeat++;
}
return target;
}
void realloc_mycatter(char **target, char *initial, char *repeat, int times)
{
char *catptr = *target = malloc(strlen(initial)+1);
strcpy(*target, initial);
for (int i = 0; i < times; i++) {
*target = realloc(*target, strlen(*target) + strlen(repeat) + 1);
catptr = mystrcat(catptr, repeat);
}
}
void prealloc_mycatter(char **target, char *initial, char *repeat, int times)
{
char *catptr = *target = malloc(strlen(initial) + strlen(repeat) * times + 1);
strcpy(*target, initial);
for (int i = 0; i < times; i++) {
catptr = mystrcat(catptr, repeat);
}
}
int main(int argc, char **argv)
{
if (argc < 4) exit(1);
char *initial = argv[1];
char *repeat = argv[2];
int times = atoi(argv[3]);
char *target;
measure("realloc_catter", realloc_catter, &target, initial, repeat, times);
measure("prealloc_catter", prealloc_catter, &target, initial, repeat, times);
measure("realloc_mycatter", realloc_mycatter, &target, initial, repeat, times);
measure("prealloc_mycatter", prealloc_mycatter, &target, initial, repeat, times);
return 0;
}
mystrcat()函数返回指向最后一个字符串位置的指针,保存下一次调用,必须再次遍历该字符串。此测试代码也可以gist。
的形式提供答案 4 :(得分:0)
正如DrKoch所提出的,多次调用realloc可能会对执行时间产生影响,具体取决于realloc的实现。
如果你已经有多少时间追加someVar,你可以一次分配所有必需的动态内存:
char *full;
char someVar[] ="test ";
int nb_append = 200;
int x = 0;
if ((full = malloc(sizeof (*full) * 8) == NULL)// allocating the memory
// Handle malloc error;
strcpy(full,"Start: ");
if (realloc(full,sizeof(*full) * 8 + sizeof(someVar) * nb_append) == NULL) //reallocating for store only once
// Handle realloc error;
while (x < nb_append ) {
strcat(full, someVar);
x++;
}
答案 5 :(得分:0)
如果迭代地重复追加字符串会导致O(n ^ 2)运行时间。相反,应该预先分配全部内存,并逐步构建字符串。
这是一些代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// append_extra returns a string consisting of init
// with count copies of extra appended.
// Or NULL on failure.
char *append_extra(char *init, char *extra, int count) {
size_t len_init = strlen(init);
size_t len_extra = strlen(extra);
char *result = malloc(len_init + len_extra * count + 1);
if (!result) {
return 0;
}
char *p = result;
strcpy(p, init);
p += len_init;
for (int i = 0; i < count; i++) {
strcpy(p, extra);
p += len_extra;
}
return result;
}
int main(void) {
char *result = append_extra("hello", " world", 10);
if (!result) exit(1);
printf("'%s'\n", result);
return 0;
}
答案 6 :(得分:0)
strcat()
您有可能会进入the Schlemiel's algorithm。
保持当前字符串长度并改为sprintf()
(或snprintf()
):
char *result;
size_t len = 0;
while (1) {
/* make sure result points to a large enough area! */
len += sprintf(result + len, "%s", "test ")
if (stuff()) break;
}