C语言传递需要初始化的字符串

有些情况下我们想让函数返回一个由该函数初始化的字符串。假设我们想传递一个部件的信息,比如名字和数量,然后让函数返回表示这个信息的格式化字符串。通过把格式化处理放在函数内部,我们可以在程序的不同部分重用这个函数。

不过,我们得决定是给函数传递一个空缓冲区让它填充并返回,还是让函数动态分配缓冲区并返回。

要传递缓冲区:

  • 必须传递缓冲区的地址和长度;
  • 调用者负责释放缓冲区;
  • 函数通常返回缓冲区的指针。

这种方法把分配和释放缓冲区的责任都交给了调用者。虽然没有必要,返回缓冲区指针很常见,strcpy或类似函数就是这种情况。下面的format函数说明了这种方法:

char* format(char *buffer, size_t size,
        const char* name, size_t quantity, size_t weight) {
    snprintf(buffer, size, "Item: %s Quantity: %u Weight: %u",
            name, quantity, weight);
    return buffer;
}

这里用了snprintf函数来简化字符串格式化,该函数写入第一个参数指向的缓冲区。第二个参数指定缓冲区的长度,函数不会越过缓冲区写入。其他方面,这个函数和printf函数的行为一样。

下面的语句说明了这个函数的用法。它假设缓冲区已被声明为一个数组。如果已动态分配缓冲区内存,则需要传入分配的内存大小,而不是使用函数的大小。

printf("%s\n",format(buffer,sizeof(buffer),"Axle",25,45));

输出如下:

Item: Axle Quantity: 25 Weight: 45

通过返回缓冲区的指针,我们可以将函数作为printf函数的参数。

还有一种方法是传递NULL作为缓冲区地址,这表示调用者不想提供缓冲区,或者它不确定缓冲区应该是多大。这样的函数实现列在了下面,在计算长度时,10 + 10子表达式表示数量和重量可能的最大宽度,而1则是为NUL终结符留下空间:

char* format(char *buffer, size_t size,
        const char* name, size_t quantity, size_t weight) {

    char *formatString = "Item: %s Quantity: %u Weight: %u";
    size_t formatStringLength = strlen(formatString)-6;
       size_t nameLength = strlen(name);
    size_t length = formatStringLength + nameLength +
        10 + 10 + 1;

    if(buffer == NULL) {
        buffer = (char*)malloc(length);
        size = length;
    }
    snprintf(buffer, size, formatString, name, quantity, weight);
    return buffer;
}

函数使用的变量取决于应用程序的需要。第二种方法的主要缺点在于调用者现在要负责释放分配的内存,调用者需要对函数的使用方法了如指掌,否则可能很容易产生内存泄漏。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程