printf
是一个很棒的函数,因为它可以帮助你以非常干净的方式格式化字符串。
printf("Player %s has lost %d hitpoints", victim.name, damage);
是否有类似的方法来连接和执行正常字符串"如下所示:
uint8_t myString = ("Player %s has lost %d hitpoints", victim.name, damage); //SOMETHING LIKE THIS
答案 0 :(得分:5)
您可以使用sprintf()
。喜欢这个
char* myString = malloc(50);
sprintf(myString, "Player %s has lost %d hitpoints", victim.name, damage);
正如您所猜测的那样,它代表 string printf
请注意sprintf()
需要char*
,而不是uint8_t
。
当然你也可以使用snprintf()
。附加的优点是您可以将要复制的字符数赋予字符串。这可以防止缓冲区溢出。
char* myString = malloc(50);
snprintf(myString, 50, "Player %s has lost %d hitpoints", victim.name, damage);
答案 1 :(得分:5)
C99的snprintf
打印到字符串并保证不会溢出缓冲区:
char msg[48];
snprintf(msg, sizeof(msg),
"Player %s has lost %d hitpoints", victim.name, damage);
snprintf
返回字符串足够大时可能写入的字符数。因此,如果返回的值等于或大于缓冲区大小,则字符串将被截断。
传递缓冲区大小为零和空指针是合法的,这样您就可以通过首先进行探测调用来进行自己的分配:
char *msg;
int n;
n = snprintf(NULL, 0,
"Player %s has lost %d hitpoints", victim.name, damage);
msg = malloc(n + 1);
n = snprintf(msg, n + 1,
"Player %s has lost %d hitpoints", victim.name, damage);
// do stuff with msg
free(msg);
在GNU编译器上,非沙漠函数asprintf
将为您做到这一点:
char *msg = asprintf("Player %s has lost %d hitpoints",
victim.name, damage);
// do stuff with msg
free(msg);
答案 2 :(得分:4)
每个人都在建议sprintf
,但在我看来,总是使用snprintf
要好得多。函数原型如下:
int snprintf ( char * s, size_t n, const char * format, ... );
第一个参数是字符串缓冲区,第二个参数是其最大容量,后跟格式说明符字符串和参数。用法示例:
char str[STR_LEN];
snprintf(str, sizeof(str), "Player %s has lost %d hitpoints", victim.name, damage);
请注意,虽然这永远不会做任何违法行为(使用sprintf
可能会产生未定义的行为),如果您的缓冲区不够长,字符串将被截断,这可能会导致一些令人惊讶的输出。最好是检查snprintf
的结果,看看有多少字符是真的写的(感谢chux指出这一点)。
如果您有兴趣能够编写类似问题的代码,其中字符串从格式化函数返回,您可能会发现Carmack的va
来自他的idTech3引擎很有趣:https://github.com/id-Software/Quake-III-Arena/blob/master/code/splines/q_shared.cpp
(第700行)。请注意,您应该了解它的工作原理及其对嵌套调用的可能影响,更不用说在多线程环境中使用它时可能出现的问题。
答案 3 :(得分:2)
试试这个
char str[MAX_LEN];
sprintf(str,"Player %s has lost %d hitpoints", victim.name, damage);
但我不确定将uint8_t*
传递给sprintf
代替char *
是否安全。 (它可能违反约束,有关类似情况的详细信息,请参阅here。)
为了更安全,你也可以使用snprintf
。
答案 4 :(得分:2)
printf("Player %s has lost %d hitpoints", victim.name, damage);
如果要将结果保存在字符串中而不是打印出来,则可以使用同一系列中的另一个函数,称为sprintf
。在你的情况下,像这样使用它:
sprintf(myString,"Player %s has lost %d hitpoints", victim.name, damage);
正如user694733指出的那样,使用snprintf
代替sprintf
通常更安全。两者之间的区别在于,对于snprintf
,您可以指定要写入字符串的最大字符数(这包括终结符char \0
!"在第二个参数中。{{ 3}}