【问题标题】:printf That Returns a String [duplicate]返回字符串的 printf [重复]
【发布时间】:2014-12-05 02:30:16
【问题描述】:

有没有像 printf 这样的函数可以返回一个字符串而不是打印它?我有一个以某种颜色打印字符串的函数,但它必须是字符串文字,而不是接受 printf 之类的变量。

// Function declaration (Assums YELLOW and NORMAL are the unix constants for terminal colors
void pYellow(char *str) {
    printf("%s%s%s", YELLOW, str, NORMAL);
}

//Function call 
void pYellow("This is a string");

如果我想用变量进行彩色打印,它就行不通了。像pYellow("Num: %d", 42); 一样会报错,因为它的参数太多了。而且pYellow(printf("String")); 也行不通。

TL:DR 我想知道是否有一个 printf 方法返回一个字符串而不是打印它。

【问题讨论】:

标签: c string function return printf


【解决方案1】:

使用snprintf:

int snprintf(char *str, size_t size, const char *format, ...);
  • str 是您分配的缓冲区(例如malloc()
  • size 是该缓冲区的大小
  • 调用后格式化的字符串存储在str中。
  • 还有sprintf千万别用

您还可以使用v*printf 系列函数创建您自己的printf 类函数。最简单的例子:

#include <stdarg.h>
// required for va_list, va_start, va_end

void customPrintf(const char* format, /* additional arguments go here */ ...)
{
    va_list args;
    va_start(args, format);
    // set color here (for example)
    vprintf(format, args);
    // reset color
    va_end(args);
}

【讨论】:

  • 不同意“sprintf,永远不要使用它”。 snprintf() 也有自己的一系列问题。为工作使用正确的工具并正确使用它。 char[sizeof(int)*CHAR_BIT/3 + 3]; sprintf(buf, "%d", some_int); 没有什么不安全的地方 如果编码人员不能正确使用sprintf(),那么正确使用snprintf() 的机会不会高很多,并且会提供错误的安全感。就像推荐 strncpy() 而不是 strcpy() - 用一组问题换另一组问题。
  • @chux 我还是更喜欢%d 的 snprintf 版本,你知道它不会缓冲溢出,而另一个你必须动脑筋检查它(即使那样你也可能不是 100% 确定)。
  • @Matt McNabb 同意 snprintf() 确实可以防止缓冲区溢出。如果缓冲区不足,则打印结果错误(截断)。代码仍然有问题。我们已经将一种问题换成了另一种问题。哪个更好是有争议的,但最后,健壮的代码需要 1)防止(sprintf() 路由)或 2)处理截断(snprintf() 路由)。 IAC - 我的观点是,它并不总是更好,而是声明“sprintf,从不使用它”并不是一个好建议,因为“从不”。
  • 我没有看到这里的问题。要么你知道缓冲区大小,那么使用 snprintf 真的没有问题。或者你不知道,那么它是完全不安全的两次写入甚至一个字节到缓冲区。由于他似乎是一个新手程序员,我宁愿给出 never 的建议。 如果你确切地知道自己在做什么就去做-建议不适合新手。顺便说一句,您是否知道 printf 输出有时取决于语言环境?截断检查=检查返回值,是不是UB。无效的内存访问 UB。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-27
  • 1970-01-01
  • 2016-07-13
  • 2020-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多