在Redis(http://code.google.com/p/redis)中有与元素相关联的分数,以便对这些元素进行排序.这个分数是双倍的,即使许多用户实际按整数排序(例如unix次).
保存数据库时,我们需要编写这个双打ok磁盘.这是目前使用的:
snprintf((char*)buf+1,sizeof(buf)-1,"%.17g",val);
Run Code Online (Sandbox Code Playgroud)
此外,还检查无穷大和非数字条件,以便在最终数据库文件中表示这一点.
不幸的是,将double转换为字符串表示非常慢.虽然我们在Redis中有一个函数,它以更快的方式将整数转换为字符串表示形式.所以我的想法是检查是否可以将double转换为整数而不丢失数据,然后使用该函数将整数转换为字符串(如果这是真的).
为了提供良好的加速,当然整数"等价"的测试必须快.所以我使用的技巧可能是未定义的行为,但在实践中效果很好.像这样的东西:
double x = ... some value ...
if (x == (double)((long long)x))
use_the_fast_integer_function((long long)x);
else
use_the_slow_snprintf(x);
Run Code Online (Sandbox Code Playgroud)
在我的推理中,上面的双重转换将double转换为long,然后转换为整数.如果范围适合,并且没有小数部分,则该数字将在转换后继续存在,并且与初始数字完全相同.
因为我想确保这不会破坏某些系统中的东西,我加入freenode上的#c并且我受到了很多侮辱;)所以我现在正在尝试这里.
有没有一种标准的方法来做我想要做的事情而不超出ANSI C?否则,上面的代码是否适用于当前Redis目标的所有Posix系统?那就是现在运行Linux/Mac OS X/*BSD/Solaris的拱门?
为了使代码更健全,我可以添加的是在尝试强制转换之前对double的范围进行显式检查.
感谢您的任何帮助.
GCC编译器如何解释以下行:
printf("HELLO");
Run Code Online (Sandbox Code Playgroud)
我想知道这个,因为当我运行以下程序时:
main()
{
printf(5+"Good Morning");
}
Run Code Online (Sandbox Code Playgroud)
该程序正在打印:
Morning
Run Code Online (Sandbox Code Playgroud)
为什么编译器从第六个字符开始打印?
我正在尝试创建一个框架来处理文件和数据.我正在努力解决的一个领域是如何为框架提供日志记录功能,允许框架在不知道正在使用的日志记录的情况下报告消息.
let testLogger (source:seq<'a>) logger =
logger "Testing..."
let length = source |> Seq.length
logger "Got a length of %d" length
let logger format = Printf.kprintf (printfn "%A: %s" System.DateTime.Now) format
testLogger [1; 2; 3] logger
Run Code Online (Sandbox Code Playgroud)
理想情况下,我希望此代码可以工作,但我无法确定如何传递记录器功能.
我正在编写一个小的c ++应用程序来包装opencv haar训练函数(即cvCreateTreeCascadeClassifier).该函数将整个输出加载到控制台,我希望解析此输出,以便我可以在我的代码中填充各种变量.
我想使用的函数不是实际的openCV库的一部分; 相反,它必须使用我的代码构建作为项目的一部分.函数的所有输出都是通过printf输出的.
问题:是否可以在最终出现在控制台上之前拦截printf语句?我已经设法使用freopen重定向它们,但这似乎有点笨拙,因为我需要解析文件然后在函数调用完成后删除它.此外,该功能可能会运行几个小时(甚至可能是几周!),因此如果文件的大小也经常被附加,那么文件的大小可能会成为问题.
要求:我需要这个应用程序是c ++并在Windows和Linux上运行(但如果需要,条件编译语句没有问题).我还希望能够在控制台上看到我的cout和cerr消息(只是不是printf).
我的谷歌搜索已经取消了我的生活意愿!任何人都可以通过代码示例或指向我应该寻找答案的地方的指针帮助解决方案吗?
谢谢
一段时间(非常长)我经常使用下面的代码 - 然后在MSVC 6上 - 确定为具有可变参数的函数格式化字符串所需的内存:
void LogPrint(const char *pszFormat, ...)
{
int nBytes;
char *pszBuffer;
va_list args;
va_start(args, pszFormat);
nBytes = vsnprintf(0, 0, pszFormat, va);
va_end(args);
// error checking omitted for brevity
pszBuffer = new char[nBytes + 1];
va_start(args, pszFormat);
vsnprintf(pszBuffer, nBytes, pszFormat, va);
va_end();
// ...
}
Run Code Online (Sandbox Code Playgroud)
您在更新版本的MSVC(我现在使用的是2010)中遇到的明显错误是:
警告C4996:'vsnprintf':此函数或变量可能不安全.请考虑使用vsnprintf_s.要禁用弃用,请使用_CRT_SECURE_NO_WARNINGS.详细信息请参见在线帮助.
我是任何C(++)编译器的"将警告视为错误"选项的忠实粉丝,显然我的构建失败了.简单地使用#pragma warning (disable:4996)并继续使用它就像欺骗我一样.
所建议的"更安全"的替代vsnprintf_s(),但是注定要返回-1时,其"不安全"前身输入条件发生.
TL/DR:有没有办法实现预期的行为,vsnprintf()使用新的,更安全的变体来返回完成任务所需的内存?
编辑:简单定义_CRT_SECURE_NO_WARNINGS不会削减它; 还有很多strcpy()飞来飞去.它的新变种没有被打破,所以我仍然希望看到这些.
如何在bash中使用printf打印格式化的系统日期+主机名.
有点像printf "%s:%s\n" date hostname?
我有一个PHP脚本,显示时间像:9.08374786377E-5,但我需要简单的浮动值作为时间像:0.00009083747 .....这就是为什么我只是用它浮动打印它:
<?php
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
$time_start = microtime_float();
$time_end = microtime_float();
$time = $time_end - $time_start;
printf('%.16f', $time);
?>
Run Code Online (Sandbox Code Playgroud)
它很好地显示了结果,但我需要在新变量中设置此打印值.我怎样才能做到这一点 ?我需要在新变量$ var中设置此打印值;
$var = printf('%.16f', $time);
Run Code Online (Sandbox Code Playgroud)
//我们都知道它不起作用,但如何设定?
假设我有一个这样的文件:
$ cat a
hello this is a sentence
and this is another one
Run Code Online (Sandbox Code Playgroud)
我想打印前两列,在它们之间有一些填充.由于这个填充可能会改变,我可以使用例如7:
$ awk '{printf "%7-s%s\n", $1, $2}' a
hello this
and this
Run Code Online (Sandbox Code Playgroud)
或者17:
$ awk '{printf "%17-s%s\n", $1, $2}' a
hello this
and this
Run Code Online (Sandbox Code Playgroud)
或者25,或......你明白了这一点:数字可能会有所不同.
然后弹出一个问题:是否可以为此分配变量N,而不是以%N-s格式对整数进行硬编码?
我尝试了这些事情没有成功:
$ awk '{n=7; printf "%{n}-s%s\n", $1, $2}' a
%{n}-shello
%{n}-sand
$ awk '{n=7; printf "%n-s%s\n", $1, $2}' a
%n-shello
%n-sand
Run Code Online (Sandbox Code Playgroud)
理想情况下,我想知道是否可以这样做.如果不是,那么最好的解决方法是什么?
我有这个C代码:
locale_t myLocale = newlocale(LC_NUMERIC_MASK, "en_US", (locale_t) 0);
uselocale(myLocale);
ptrLocale = localeconv();
ptrLocale->thousands_sep = (char *) "'";
int i1 = snprintf( s1, sizeof(s1), "%'d", 123456789);
Run Code Online (Sandbox Code Playgroud)
输出s1是123,456,789.
即使我设置->thousands_sep到'它被忽略.有没有办法将任何字符设置为千位分隔符?
该printf系列函数提供一系列长度改性剂,其中的两个是hh(表示一个signed char或unsigned char参数升为int)和h(表示一个signed short或unsigned short参数升为int).从历史上看,这些长度修饰符仅用于创建长度修饰符的对称性,scanf很少用于printf.
以下是ISO 9899:2011§7.21.6.1"fprintf函数"7的摘录:
7长度修饰符及其含义是:
hh用于指定后续的d,i,o,u,x,或X转换说明适用于一个signed char或unsigned char参数(该参数将被提升根据整数促销,但它的值应被转换成signed char或unsigned char之前印刷); 或者以下n转换说明符适用于指向signed char参数的指针.
h用于指定后续的d,i,o,u,x,或X转换说明适用于一个short int或unsigned short int …