在C语言中从变量构建字符串

23

我正在制作一个使用套接字的基本二十一点游戏,这得益于我的操作系统课程。我们已经拥有了一个传递字符数组的套接字接口。

我曾经希望能够像这样做:

char[] msgOut = printf("Dealer's Card is %C %C", char1, char2);
sendMsg(msgOut);

然而,通过谷歌搜索我发现printf函数的返回值是输出字符数的int类型,并不是我所希望的字符本身的char[]数组。

还有其他的C函数可以让我用变量生成字符串吗?

3个回答

41

printf函数将内容输出到标准输出。snprintf函数可以实现你想要的功能。插值字符串会在调用snprintf后存储在'buffer'中。你可能想要更加智能地定义缓冲区大小,但这只是一个例子。

char buffer[1024];
snprintf(buffer, sizeof(buffer), "Dealer's Card is %C %C", char1, char2);

1
不,看这个例子。缓冲区将会被原地修改。C语言中的许多函数返回错误代码并在原地修改它们的参数。你必须习惯在C语言中编写代码时遇到这种情况。 - Ed S.
1
@EdS.:如何将内容添加到“buffer”中。比如我想多次调用“snprintf”函数,但不希望“buffer”中的文本被覆盖。 - arunmoezhi
@arunmoezhi:传递指向缓冲区内某个偏移量的指针,即 buffer + n, sizeof(buffer) - n - Ed S.
@EdS.:我应该在每次调用后递增 n 吗? - arunmoezhi
@arunmoezhi:n只是偏移量,它可以是你需要的任何值。 - Ed S.
显示剩余3条评论

13

Glibc(以及其他几个C库)有一个方便的函数asprintf

char *msgOut;
asprintf(&msgOut, "Dealer's Card is %C %C", char1, char2);
sendMsg(msgOut);
free(msgOut);

如果你无法预测字符串所需的内存量,那么此时最有用的是使用此方法。(如果你能够预测,snprintf 的开销较小,因为它不会动态分配内存)

在没有 asprintf 但有符合标准的 snprintf 的系统上,可以通过两次调用 snprintf 来实现此功能——首先使用零大小和无缓冲区来确定字符串长度,然后进行一个 malloc ,最后再一次使用新分配的空间。


2
如果你需要一个在c中动态分配内存的字符串构建器,我发现http://linux.die.net/man/3/vasprintf非常有用。
例如:
#include <stdio.h>

int i;
printf("//Simple dynamic string builder:\n");
char *strs[6] = {"I","am","an","array","of","strings"};

char *buf = "["; // open bracket
for (i=0;i<6;i++) {
    // Dynamically build and allocate memory
    asprintf(&buf,"%s%s",buf,strs[i]);
    if(i!=5) { // Add a comma , after each but skip the last
        asprintf(&buf,"%s,",buf);
    }
}
asprintf(&buf,"%s]",buf); // closing backet
printf("\"%s\"\n",buf);

输出结果为:
//Simple string builder:
"[I,am,an,array,of,strings]"

所以char *buf是通过asprintf动态扩展的,并且通过将自身格式化为asprintf语句来构建。


2
请注意,asprintf 是 GNU 扩展,而不是 C/POSIX 的事实标准方法。 - Reuel Ribeiro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接