像 printf 一样连接一个字符串
Concatenate a string like in printf
printf
是一个漂亮的函数,因为它可以帮助您以非常干净的方式格式化字符串。
printf("Player %s has lost %d hitpoints", victim.name, damage);
是否有类似的方法在 "normal string" 中连接和执行强制转换,如下所示:
uint8_t myString = ("Player %s has lost %d hitpoints", victim.name, damage); //SOMETHING LIKE THIS
您可以使用 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);
这样试试
char str[MAX_LEN];
sprintf(str,"Player %s has lost %d hitpoints", victim.name, damage);
但我不确定将 uint8_t*
传递给 sprintf
而不是 char *
是否安全。 (这可能违反约束,有关类似情况的更多详细信息,请参阅 here)。
确实为了更安全,您也可以使用 snprintf
。
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
,您可以在第二个参数中指定要写入字符串的最大字符数(这包括终止符字符 [=16=]
!")。More info on snprintf
每个人都在建议 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 行)。请注意,您应该了解它的工作原理及其对嵌套调用的可能影响,更不用说在多线程环境中使用它时可能出现的问题了。
C99 的 snprintf
打印到一个字符串并保证不会溢出缓冲区:
char msg[48];
snprintf(msg, sizeof(msg),
"Player %s has lost %d hitpoints", victim.name, damage);
snprintf
returns 如果字符串足够大,可以写入的字符数。因此,如果返回值等于或大于缓冲区大小,则字符串被截断。
传递零缓冲区大小和空指针是合法的,这样您就可以通过先进行探测调用来进行自己的分配:
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);
printf
是一个漂亮的函数,因为它可以帮助您以非常干净的方式格式化字符串。
printf("Player %s has lost %d hitpoints", victim.name, damage);
是否有类似的方法在 "normal string" 中连接和执行强制转换,如下所示:
uint8_t myString = ("Player %s has lost %d hitpoints", victim.name, damage); //SOMETHING LIKE THIS
您可以使用 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);
这样试试
char str[MAX_LEN];
sprintf(str,"Player %s has lost %d hitpoints", victim.name, damage);
但我不确定将 uint8_t*
传递给 sprintf
而不是 char *
是否安全。 (这可能违反约束,有关类似情况的更多详细信息,请参阅 here)。
确实为了更安全,您也可以使用 snprintf
。
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
,您可以在第二个参数中指定要写入字符串的最大字符数(这包括终止符字符 [=16=]
!")。More info on snprintf
每个人都在建议 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 行)。请注意,您应该了解它的工作原理及其对嵌套调用的可能影响,更不用说在多线程环境中使用它时可能出现的问题了。
C99 的 snprintf
打印到一个字符串并保证不会溢出缓冲区:
char msg[48];
snprintf(msg, sizeof(msg),
"Player %s has lost %d hitpoints", victim.name, damage);
snprintf
returns 如果字符串足够大,可以写入的字符数。因此,如果返回值等于或大于缓冲区大小,则字符串被截断。
传递零缓冲区大小和空指针是合法的,这样您就可以通过先进行探测调用来进行自己的分配:
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);