今天忙活了半个下午,查找正式环境上面一个程序的问题。这个程序的作用是监控文件夹,处理每一个文件,分析每个文件的每行记录,然后将这个文件拆分成两个结果文件投放到另外两个不同的目录下面去,当处理完这个文件后,将源文件剪切到备份文件夹下面去。程序的整体逻辑很简单,只用了一天的时间就完成了。可在测试工作完成后,部署到正式环境上面后,今天维护人员突然说有问题,说程序一直在处理一个文件,并且是死循环,处理的结果文件一直在增大,都已经有50多G了。我根据他的描述,说是死循环,一直在处理某个文件。然后我把这个文件取下来单独在测试环境下面测试,一切正常。说明不是文件内容的问题,我想到了文件操作时是不是磁盘坏道的问题,于是乎我一下子就想到代码里的有一个地方可能有问题。这段逻辑大概是这样的:

while(!fs.eof())   // fs的类型是std::fstream
{
std::string str;
std::getline(fs, str);
...
...
}

我就断定代码一定是在这里出问题了,你发现了吗?这个getline竟然没有返回值判断耶,so shit!,当时我这么想的,假如getline出错了,会设定ios::badbit的标记位,这个fstream就不是一个正常的IO了,我也没有做异常处理,接下来程序会一直在这个while循环里做死循环, 因为这个文件不可能会读到文件末尾,也就不会出现读到eof。 接下来我在SO(stack overflow)上面查有没有类似问题,很幸运,竟然有人遇到过类似的问题。我真的只能说 “so sorry that, I am a beginner.”

回到家后,重新打开电脑写了关于getline的程序来验证我的想法,这样做确实会导致死循环的出现(把if判断异常的代码去除)。代码如下:

#include <iostream>
#include <cstdio>
#include <fstream>
#include <string> int main()
{
std::fstream fs;
fs.open("/home/f_x_p/test_code/c++/testfile");
if(!fs.is_open()){
std::cerr << "file open failed!" << std::endl;
return -;
}
int i = ;
while(!fs.eof())
{
std::string str;
if(!std::getline(fs, str)){
std::cerr << "getline failed!" << std::endl;
if((fs.rdstate() & std::fstream::eofbit) != )
{
continue;
}else{
fs.clear();
}
}
std::cout << str << std::endl;
if(i == ){
fs.setstate(std::fstream::badbit);
++i;
}
}

  return 0;
}

网上认识的水晶大牛说我应该没那么倒霉,这个地方出错的概率很小。结果如他所说,最终排查的结果不是代码的问题,是维护人员把配置文件搞错了。但我也很自责,配置文件出错,竟然导致了程序的死循环。我只能说 "my code is so shit."

今天真的是血的教训,一个健壮的程序真的是太重要了,以前在代码的健壮性方面确实思考的太少。

记一次程序排错与std::getline的更多相关文章

  1. 记一次zabbix排错(数据库安装在其它服务器上)

    记一次zabbix排错 故障现象 1.在/var/log/zabbix/zabbix_server.log中出现以下报错: 12106:20190314:090947.010 [Z3001] conn ...

  2. 【转】java线上程序排错经验2 - 线程堆栈分析

    前言 在线上的程序中,我们可能经常会碰到程序卡死或者执行很慢的情况,这时候我们希望知道是代码哪里的问题,我们或许迫切希望得到代码运行到哪里了,是哪一步很慢,是否是进入了死循环,或者是否哪一段代码有问题 ...

  3. 利用c++ std::getline实现split

    getline reads characters from an input stream and places them into a string: getline从输入流中读取字符, 并把它们转 ...

  4. 记32位程序(使用3gb用户虚拟内存)使用D3DX9导致的一个崩溃的问题

    为了增加32位程序的用户虚拟内存的使用量,我们使用了/LARGEADDRESSAWARE编译选项来使32位程序可能使用到3gb的内存,能否使用到3gb内存也跟平台.系统和设置有关系,现摘抄部分作为参考 ...

  5. 小程序排错(redis导致)

    小程序突然出问题,题库加载不了,程序正常,测试环境同样环境,同样代码都正常,但是线上数据秒过期,怀疑redis过期时间设置有问题,但是检查配置没问题,写入数据带过期时间也正常. redis设置key: ...

  6. 记一次samba排错 Failed to start Samba SMB Daemon.

       记录一次服务出错排错的过程,很多新手出了点错不百度直接巴拉巴拉的问,一般老手根据经验可以给出一点建议,但是由于个体环境的差异并不适用,反而埋怨起来.这种真的无F**K可说,所以要培养自己的排错能 ...

  7. 小程序红包开发跳坑记 微信小程序红包接口开发过程中遇到的问题 微信小程序红包开发

    现在做小程序的越来越多,商家推广也是一个瓶颈,谁不发点红包,都很难找到人来用你的微信小程序了.于是不管你开发什么小程序功能,你或多或少都要用到小程序来发红包吧.  我们自己之前做公众号发红包,做了两三 ...

  8. TFboy养成记 简单小程序(Variable & placeholder)

    学习参考周莫烦的视频. Variable:主要是用于训练变量之类的.比如我们经常使用的网络权重,偏置. 值得注意的是Variable在声明是必须赋予初始值.在训练过程中该值很可能会进行不断的加减操作变 ...

  9. 记一次程序从x86_64linux平台移植到armv7平台

    前言 最近接了个任务,需要把代码移植到armv7平台,搜寻相关方法,了解到可以利用交叉编译工具如:gcc-linaro-arm-linux-gnueabihf.把自己依赖的第三方库代码和自己代码分别编 ...

随机推荐

  1. liunx中计算机壳层

    什么是shell?shell是用C语言编写的程序.既是一种命令语言,又是一种程序设计语言.shell是一种应用程序,这个应用程序提供一个界面,用户通过这个界面访问系统内核的服务.在计算机科学中,She ...

  2. 解决selenium2在IE11上出错的问题,如Unable to get browser

    官方解决方案: https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver#required-configuration Re ...

  3. java开发JDBC连接数据库详解

    JDBC连接数据库 好文一定要让大家看见 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机) ...

  4. NSString 和NSData 转换

    NSString 转换成NSData 对象 NSData* xmlData =[@"testdata" dataUsingEncoding:NSUTF8StringEncoding ...

  5. PHP【函数】

    目录:[PHP函数].[PHP数组] 一.PHP常用函数(和JS一样)函数的四要素:①返回类型②函数名③参数类型④函数体因为PHP是弱类型语言,所以可以不用写返回类型,但是其他三个要素都是必须要写的. ...

  6. C#向Sql数据库插入控制

    string name = textBox1.Text; int age = Convert.ToInt32(textBox2.Text.Trim()); ? null : (int?)Convert ...

  7. Spring Web MVC 多viewResolver视图解析器解决方案

    viewResolver的定义如下: public interface ViewResolver { View resolveViewName(String viewName, Locale loca ...

  8. python中read、readline、readlines的区别

    read直接读入整个文件,存成一个字符串变量 readline一行一行读入文件,所以说读取的文件可以大于内存,但是读取的速度很慢 readlines一次读取整个文件,存成一个列表,所以说也必须小于内存 ...

  9. 浏览器-04 WebKit 渲染2

    渲染主循环(main loop)和requestAnimationFrame requestAnimationFrame 使用requestAnimationFrame而非setTimeout/set ...

  10. Hdu5093 Battle ships 二分图

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission( ...