从具有意外长度的函数返回字符串?

时间:2010-10-03 03:55:12

标签: c string

C对于字符串来说总是很尴尬,但是通常可以为你的字符串分配一个大小为256的字符数组并使用它。

但是,如果你希望函数返回一个字符串并且你不知道它的大小,那么你会将字符串连接几十次或几百次呢?显然这样的事情是行不通的:

char * my_function(int n, char *string){
    if (n < 20) {
        return string;
    }
    else {
        char *new_string = "abcdefghijklmnop";
        strcat(string, new_string);
        return my_function(n--, string);
    }
}

那么如何在c中处理?

5 个答案:

答案 0 :(得分:4)

执行连接任意数量字符串的函数的最简单方法是:

  1. 遍历所有字符串并添加strlen()
  2. malloc()了解总长度。
  3. 执行malloc'字符串中的所有连接,然后将其返回。

答案 1 :(得分:3)

你的第一段做了一些非常糟糕的假设。我希望你不是那样做的。

在任何情况下,通用解决方案都是在任何地方使用动态分配并不断重新分配。然而,这是低效的,更好的方法可能是改变你想要连接字符串的假设(更少数百次),而是在单个操作中用snprintf构造字符串。然后,您可以先计算所需的大小,然后可以选择分配它,或者只使用固定大小的缓冲区,输出可能会被截断。

答案 2 :(得分:1)

有几种常见的方法可以处理最终大小未知的返回字符串:

  • 您使调用者负责传入一个缓冲区,以获得足够大的结果来保存结果。如果你这样做,你应该要求调用者也传入缓冲区的大小,这样如果结果太大而不是超越缓冲区就可以返回错误(即,跟随snprintf()的示例而不是sprintf()')。

  • 您可以动态分配结果的内存,并让调用者负责释放内存

为您my_function()添加了几个(未经测试的)示例:

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

/*
  create new string in a dynamically allocated buffer
 */
char * my_function1(int n, char *s1)
{
    static char const new_string[] = "abcdefghijklmnop";

    int sz = strlen(s1) + (n * strlen(new_string)) + 1;

    char* result = malloc(sz);

    if (result) {
        strcpy(result, s1);

        while (n--) {
            strcat(result, new_string);
        }
    }

    return result;
}


/*
  create new string in a caller provided buffer
 */
int my_function2(int n, char *s1, char* buf, int buf_size)
{
    static char const new_string[] = "abcdefghijklmnop";

    int sz = strlen(s1) + (n * strlen(new_string)) + 1;

    if (sz > buf_size) {
        return -1; /* error */
    }

    strcpy(buf, s1);

    while (n--) {
        strcat(buf, new_string);
    }

    return sz-1; /* characters in result */
}

答案 3 :(得分:0)

你会想要使用这样的东西:

void my_function ( ..., char ** result )
{
    // decide how many bytes...

    // Allocate enough memory.
    (*result) = malloc(number_of_bytes);

    // Fill the buffer...
}

答案 4 :(得分:0)

有一种方法可以使用 realloc 在原始字符串上添加任意长度的字符串。您不需要知道字符串的最终长度。

我假设您可以安全地修改调用函数中传递的参数string的声明/初始化为:

char * string = calloc( 0, sizeof(char) ); 

将0替换为字符串最初的大小,加上1表示终止NULL。

将您的功能更改为:

 char * my_function(int n, char *string){
    if (n < 20) {
        return string;
    }
    else 
    {
        char *new_string = "abcdefghijklmnop";
        if( (temp = realloc(string, strlen(new_string)+ strlen(string) + 1)) == NULL )
        { 
          printf("Memory allocation error"); 
          exit(1); 
        }
        strcat(string, new_string);
        return my_function(n--, string);
    }
}