sprintf 无效格式 '%d'

Posted

技术标签:

【中文标题】sprintf 无效格式 \'%d\'【英文标题】:sprintf invalid format '%d'sprintf 无效格式 '%d' 【发布时间】:2015-01-22 07:36:13 【问题描述】:

这行得通:

> sprintf('%d', c(1, 1.5))
[1] "1" "1"

这不是:

> sprintf('%d', c(1.5, 1))
Error in sprintf("%d", c(1.5, 1)) : 
  invalid format '%d'; use format %f, %e, %g or %a for numeric objects

为什么?

【问题讨论】:

我知道我可以使用sprintf('%.f', c(1.5, 1)) 之类的东西,但我想了解%d 发生了什么 我正在沉思sprintf.c,到目前为止,很难确切地说出为什么这种行为是不对称的。 ns = 0 有一条关于强制尝试的评论,尽管它周围的代码很神秘。 @RichardScriven 帮助文件中有什么内容? 可能重复:***.com/questions/10786169/… @PascalvKooten 这不能回答为什么第一个案例有效。阅读我的第一条评论 【参考方案1】:

这实际上是一个非常有趣的问题。首先,%d 代表整数。如果可能,vector 参数会被回收,但如果它是 c(1.5, 1),它将在 sprintf() 尝试用 1.5(不是整数)替换 %d 时失败。

我认为这可能与R中整数和双精度都是数字模式有关,例如:

storage.mode(c(1.5, 1))
# [1] "double"
storage.mode(c(1, 1.5))
# [1] "double"
mode(c(1,1.5))
# [1] "numeric"
mode(c(1.5,1))
# [1] "numeric"

因此,两个向量都应存储为双精度。 R language definition 和 ? numeric 的文档中有关矢量的更多信息:

潜在的混淆是 R 使用模式“数字”来表示“双精度或整数””

我可能在the underlying C code 中找到了解释发生了什么的行:

if(TYPEOF(_this) == REALSXP) 
double r = REAL(_this)[0];
if((double)((int) r) == r)
_this = coerceVector(_this, INTSXP);

此代码执行以下操作:如果向量类型为REALSXP(表示数字),则将向量的第一个成员转换为double r。然后将r 转换为整数然后加倍,如果字节仍然相同,则将整个向量转换为INTSXP。重要的是,这段代码只检查向量的第一个元素;如果该元素可以强制为整数,则强制整个向量,否则代码会出错。

为了验证这一假设,可以使用自定义 sprintf() 编译 R,其中 double r = REAL(_this)[0]; 更改为 double r = REAL(_this)[1]; 并测试 c(1.5, 1) 现在是否有效。

【讨论】:

抱歉,我不明白这如何解释 c(1.5, 1)c(1, 1.5) 之间的差异 可以从这里找到确切的答案:rsource/sprintf.c。如果有更多 C 经验的人可以找到它? 很好的答案,奇怪的实现。出于性能原因,必须这样做。

以上是关于sprintf 无效格式 '%d'的主要内容,如果未能解决你的问题,请参考以下文章

格式化输出字符串——sprintf

PHP 格式化字符串sprintf()

c语言中的sprintf函数?

PHP sprintf() 函数

R语言sprintf函数按照C语言的方式格式化输出实战

linux中sprintf函数怎么用