我在两个不同版本的编译器中有不同的 scanf 函数行为。
int number;
int offset = 0;
const char* ref = "123456";
sscanf(ref, "%d %n", &number, &offset);
我不明白为什么 Visual Studio 2013 版本 12.0 偏移量 == 4 和 Visual Studio 2017 版本 15.9 偏移量 == 6。这是旧版本的错误吗? 当我删除空格时,两个版本都显示正确的数字:
sscanf(ref, "%d%n", &number, &offset);
%d%n 与 %d%n 有何不同?
最佳答案
How
%d%nis different from%d %n?
第一个只计算 %d 使用的字符,而后者还计算任何可能跟随的空白字符。
#include <cstdio>
#include <iostream>
void test(const char * ref, const char * fmt)
{
std::cout << "fmt: \"" << fmt << "\" ref: \"" << ref << "\"" << std::endl;
int number;
int offset = 0;
int ret = std::sscanf(ref, fmt, &number, &offset);
std::cout << " - Returned: " << ret << " Offset: " << offset << " Number: " << number << std::endl;
}
int main(int argc, char* argv[])
{
test("123456", "%d %n");
test("123456", "%d%n");
test("123456 ", "%d %n"); // case 3
test("123456 ", "%d%n"); // case 4
}
( Live on ideone );输出:
fmt: "%d %n" ref: "123456" - Returned: 1 Offset: 6 Number: 123456 fmt: "%d%n" ref: "123456" - Returned: 1 Offset: 6 Number: 123456 fmt: "%d %n" ref: "123456 " - Returned: 1 Offset: 8 Number: 123456 fmt: "%d%n" ref: "123456 " - Returned: 1 Offset: 6 Number: 123456
请注意,在情况 3 中如何计算 2 个附加的空白字符(因此偏移量 = 8),而在情况 4 中它们不被计算在内(因此偏移量 = 6)。
I don't understand why for Visual Studio 2013 version 12.0 offset == 4 and for Visual Studio 2017 version 15.9 offset == 6. Is it bug of older version?
这确实像是一个错误。可能性:
%d %n 被解释为在数字后需要空格,以便 %n“生效”。您输入的“123456”后面没有空格,因此 offset 未定义。这违反了标准,因为它明确表示格式字符串中的空白字符匹配输入字符串中的零个或多个 空白字符。确切的措辞:“由空白字符组成的指令是通过读取输入直到第一个非空白字符(保持未读)来执行的,[..] 该指令永远不会失败。” ( N1570§7.21.6.2/5 )
旧平台上的 sizeof(int) 太小,无法表示数字 123456。
min allowed maximum value of a signed int is
32767(thanks @MartinYork)
这意味着 %d 的 sscanf 只能读取 12345 但不能读取 123456,从而留下6 在输入中。不过,这应该导致偏移量为 5,而不是 4!
解决方案:先判断是需要%d%n还是%d%n的语义,再添加测试用例你的测试套件(你有一个,不是吗?)以确保提供的功能符合你的期望。如果需要,提供自己的实现。
关于c++ - 切换到新编译器后 sscanf 的工作方式有所不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55752971/
我正在从erb文件切换到HAML。我将hamlgem添加到我的系统中。我创建了app/views/layouts/application.html.haml文件。我应该只删除application.html.erb文件吗?此外,仍然有/public/index.html文件被呈现为默认页面。我想创建自己的默认index.html.haml页面。我应该把它放在哪里以及如何使系统呈现该文件而不是默认索引文件?谢谢! 最佳答案 是的,您可以删除任何已转换为HAML的View的ERB版本。至于你的另一个问题,删除public/index/h
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)
A/ctohttp://wiki.nginx.org/CoreModule#usermaster进程曾经以root用户运行,是否可以以不同的用户运行nginxmaster进程? 最佳答案 只需以非root身份运行init脚本(即/etc/init.d/nginxstart),就可以用不同的用户运行nginxmaster进程。如果这真的是你想要做的,你将需要确保日志和pid目录(通常是/var/log/nginx&/var/run/nginx.pid)对该用户是可写的,并且您所有的listen调用都是针对大于1024的端口(因为绑定(
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法在sinatra的beforedoblock中停止执行并返回不同的值?beforedo#codeishere#Iwouldliketo'return"Message"'#Iwouldlike"/home"tonotgetcalled.end//restofthecodeget'/home'doend 最佳答案 beforedohalt401,{'Content-Type'=>'text/plain'},'Message!'end如果你愿意,你可以只指定状态,这里有状态、标题和正文的例子
我想用sunspot重现以下原始solr查询q=exact_term_text:fooORterm_textv:foo*ORalternate_text:bar*但我无法通过标准的太阳黑子界面理解这是否可能以及如何实现,因为看起来:fulltext方法似乎不接受多个文本/搜索字段参数我不知道将什么参数作为第一个参数传递给fulltext,就好像我通过了"foo"或"bar"结果不匹配如果我传递一个空参数,我得到一个q=*:*范围过滤器(例如with(:term).starting_with('foo*')(顾名思义)作为过滤器查询应用,因此不参与评分。似乎可以手动编写字符串(或者可能使