Dev-C++下使用scanf("lld", nX)读取long long时出现的bug

   首先,要再现bug得先准备bug条件,使用Windows下的Dev-C++按照目录下bin文件夹下面的c和c++编译器和链接器,可以直接使用Dev-C++,或者用CodeBlocks然后编译链接的目录设置为Dev-C++的bin目录。这个bug是在今天月赛时候出现的,我用%lld读入一个不大的整数后,再for循环读入其它一些数字,发现无论如何输出不了,而我用cin和cout操作longlong的时候,超时1倍多,很恶心的出题人,本来就是一个水题,居然做成这样。然后没办法,快结束的时候,问旁边的队友,因为是个人赛,所以是自己在做,longlong,如何读入,他说%lld。是啊,我一直这样读,这样输出,为啥出问题了。。。没办法照着他的样子,把输入改成了int,直接%d读入,答案还是longlong,再%lld输出就没超时了,真恶心的一天啊。    
   64位本来就用得不多,而且对于大多数Windows下的用户,基本都是vc6和vs08什么的。vs08我已经实验过,不会出现这个bug,PS:是完全一样的代码,亲自单步调试实验的,无任何bug。vc6只能用%I64d输入和输出。那么,问题就只是在Dev-C++的用户中存在了。   回来的时候,我就决心找出问题的所在。所以,我打算升级g++的版本。下了个Dev-C++ 5.0也没用,和前面的Dev-C++ 4.9.9.2一样的,恶心啊。
     然后google+百度了很久,发现CSDN上一篇博文解释说,这就是Dev-C++自己的事情。因为gcc本来是linux下的,所以longlong在自己家里是不会出现问题的。而Dev-C++是把人家移植过来的,那篇博文说Dev-C++的编译和链接器是mingw32-g++.exe,但是Mingw32在编译期间使用gcc的规则检查语法,在连接和运行时使用的却是Microsoft库。这个库里的printf和scanf函数当然不认识linux gcc下"%lld"和"%llu",对"%I64d"和"%I64u",它则是乐意接受的。Mingw32在编译期间使用gcc的规则检查语法,在连接和运行时使用的却是Microsoft库。这个库里的printf和scanf函数当然不认识linux gcc下"%lld"和"%llu",对"%I64d"和"%I64u",它则是乐意接受的。意思是,程序里面实质的二进制代码可能是微软的库,只解析%I64d,然后就可能出错了。具体是什么原因,只有开发Dev-C++的人知道了。或者其它高人。。。

#include <stdio.h>
#include <iostream>
using namespace std;

int main()
{
    long long nN;
    long long nX, nY;

    if (scanf("%lld", &nN) != EOF)
    {
        printf("nN:%lld\n", nN);
        
        for (long long i = 0; i < nN; ++i)
        {
            printf("nN:%lld i:%lld\n", nN, i);
        }
        getchar();
        printf("Over\n");
    }

    return 0;
}


该代码会一直死循环,大家可以试试


如果改成下面这样,还可以看到输入的数据都没有到达指定的变量
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
    long long nN;
    long long nX, nY;
    
    if (scanf("%lld", &nN) != EOF)
    {
        printf("nN:%lld\n", nN);
        
        for (long long i = 0; i < nN; ++i)
        {
            printf("nN:%lld i:%lld\n", nN, i);
            scanf("%lld %lld", &nX, &nY);
            printf("nX:%lld nY:%lld\n", nX, nY);
        }
        getchar();
        printf("Over\n");
    }
    return 0;
}

posted on 2011-12-11 18:20 yx 阅读(5279) 评论(11)  编辑 收藏 引用 所属分类: C++

评论

# re: Dev-C++下使用scanf("lld", nX)读取long long时出现的bug 2011-12-11 18:59 泡菜

C99里面的long longC++98里是木有的,只是大多数编译器,扩展支持(C++2011里正式支持),有些库是用的宏。。。。貌似Dev-C++用的是GCC3.X的编译器,mingw库也比较老,干吗不试试这个---TDM-GCC ???
最新版本为 4.6.1,32位64位都有,它与CodeBlocks整合的很好  回复  更多评论   

# re: Dev-C++下使用scanf("lld", nX)读取long long时出现的bug 2011-12-11 19:04 泡菜

另,提醒声C里面的printf和scanf函数属于不太安全的函数,用的时候小心,相关资料可以参看,看雪的Oday书。。。
好好的C++ Code干吗用这两个函数泥?std::cout std::endl不能解决问题木?。。。唉!  回复  更多评论   

# re: Dev-C++下使用scanf("lld", nX)读取long long时出现的bug 2011-12-11 19:08 泡菜

最后: GCC for Window不链接微软的库,未必还链接其他操作系统的库木?微软的可执行文件为PE格式,Linux是ELF格式。。。。。  回复  更多评论   

# re: Dev-C++下使用scanf("lld", nX)读取long long时出现的bug 2011-12-11 21:41 远行

当然是不能解决问题,我才用这种函数的,cin和cout消耗的时间是scanf和printf的2倍不止。。。@泡菜
  回复  更多评论   

# re: Dev-C++下使用scanf("lld", nX)读取long long时出现的bug 2011-12-11 21:43 远行

我难道不知道是PE格式,我还分析过PE写过病毒了,微软自己实现了套C和C++库,你不会不知道吧,和gcc,g++版本是不同的@泡菜
  回复  更多评论   

# re: Dev-C++下使用scanf("lld", nX)读取long long时出现的bug 2011-12-11 22:38 远行

很不幸的是我刚按照了TDM-gcc最新版本4.61,然后用CodeBlocks关联,该问题同样存在,不过谢谢你推荐了这个编译器@泡菜
  回复  更多评论   

# re: Dev-C++下使用scanf("lld", nX)读取long long时出现的bug 2011-12-12 10:20 coolypf

@远行
与gcc无关,
是libc的问题(即msvcrt)
最新的版本是支持%lld的  回复  更多评论   

# re: Dev-C++下使用scanf("lld", nX)读取long long时出现的bug 2011-12-12 13:13 泡菜

cin和cout消耗的时间是scanf和printf的2倍不止。。。。拿你木语言老

有空推荐看看,编译器实现方面的书,CRT的实现方面。。。
在C++镶嵌C要小心


  回复  更多评论   

# re: Dev-C++下使用scanf("lld", nX)读取long long时出现的bug 2011-12-12 15:27 远行

是啊,所以我在文章里面的说法是对的,链接库里面实际上是微软实现的@coolypf
  回复  更多评论   

# re: Dev-C++下使用scanf("lld", nX)读取long long时出现的bug 2011-12-12 15:28 远行

c++里面也有scanf和printf,也不能说得上镶嵌吧@泡菜
  回复  更多评论   

# re: Dev-C++下使用scanf("lld", nX)读取long long时出现的bug 2011-12-21 12:50 ->->

@泡菜
这是在写ACM代码,没有安全不安全可言。  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2011年12月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

导航

统计

公告

常用链接

留言簿(3)

随笔分类

随笔档案

me

好友

同学

网友

搜索

最新评论

阅读排行榜

评论排行榜