最近在做一个从groundtruth_rect.txt中读取按行存储的矩形元素(x, y, w, h),文本存储的格式如下:

310,102,39,50
308,100,39,50
306,99,39,50
306,98,38,49
304,97,38,49
303,96,37,48

一般处理这种带格式的存储数据,我最喜欢的就是C语言中的格式化的输出和输入fprintf和fscanf,因为知道格式,所以一个循环反复就可以将矩形从txt中提取出来,非常的简单方便。可是当我定义了一个FILE* file = fopen("groundtruth_rect.txt","r");时程序总是有一个bugger,编译器(VS2010)输出的错误信息是:

error C2679: 二进制“=”: 没有找到接受“FILE *”类型的右操作数的运算符(或没有可接受的转换)
1>          C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winbase.h(6618): 可能是“_WIN32_FIND_DATAA &_WIN32_FIND_DATAA::operator =(const _WIN32_FIND_DATAA &)”


调来调去也没有找到错误原因,在网上也没有找到相关的提示。我猜测原因可能是由于在程序中定义了和包含了一下东西以方便我能够进行文件夹下的序列图像的路径获取:


#define _AFXDLL

#define _WIN32_WINNT 0x0502 

#include <WinBase.h>

#include <ShlObj.h>

#include <afxdlgs.h>

#include <atlstr.h>


(如果有“同道中人”希望能指点一二)

如果去掉上面的那一部分所有的bugger就消失了。因为必须用到上面获取路径的办法,所以只好放弃使用FILE *这种C语言的文件操作,转而使用C++提供的文件操作方法:

string line;

getline(file, line);

istringstream linestream(line);

string x1, y1, w1, h1;

getline(linestream, x1, ',');

getline(linestream, y1, ',');

getline(linestream, w1, ',');

getline(linestream, h1, ',');

int x = atoi(x1.c_str());

int y = atoi(y1.c_str());

int w = atoi(w1.c_str());

int h = atoi(h1.c_str());

groundtruth_rect[i] = Rect(x, y, w, h);

上面这段代码是一种比较好的方法,在运行中没有出现错误。采用的完全是按照字符来对待,以 ‘,’ 作为行的getline的结尾,一行一行的读取数据,然后再利用atoi()将字符串转变为数字,也就实现了格式化读取数据的目的。
下面先给出使用getline的范例
<span style="font-size:18px;">// string_getline_sample.cpp
// compile with: /EHsc
// Illustrates how to use the getline function to read a
// line of text from the keyboard.
//
// Functions:
//
// getline Returns a string from the input stream.
////////////////////////////////////////////////////////////////////// #pragma warning(disable:4786)
#include <string>
#include <iostream> using namespace std ; int main()
{
string s1;
cout << "Enter a sentence (use <space> as the delimiter): ";
getline(cin,s1, ' ');
cout << "You entered: " << s1 << endl;;
}</span>

然后再给出atoi()的使用范例:atoi会把能够解释为数字的字符串转变为整形数据,从字符串的开头一直到第一个不能被解释为数字的字符为止,比如“\0”等。


<span style="font-size:18px;">// crt_atoi.c
// This program shows how numbers
// stored as strings can be converted to
// numeric values using the atoi functions. #include <stdlib.h>
#include <stdio.h>
#include <errno.h> int main( void )
{
char *str = NULL;
int value = 0; // An example of the atoi function.
str = " -2309 ";
value = atoi( str );
printf( "Function: atoi( \"%s\" ) = %d\n", str, value ); // Another example of the atoi function.
str = "31412764";
value = atoi( str );
printf( "Function: atoi( \"%s\" ) = %d\n", str, value ); // Another example of the atoi function
// with an overflow condition occuring.
str = "3336402735171707160320";
value = atoi( str );
printf( "Function: atoi( \"%s\" ) = %d\n", str, value );
if (errno == ERANGE)
{
printf("Overflow condition occurred.\n");
}
}</span>

输出为:

Function: atoi( "  -2309 " ) = -2309
Function: atoi( "31412764" ) = 31412764
Function: atoi( "3336402735171707160320" ) = 2147483647
Overflow condition occurred.


但一开始并没有想到这种方法,而是采用了一个比较笨的办法,刚开始还能正确读取数据,可是读到一半的时候居然读出的数据全是0了,我也真是快疯了(本来痛痛快快的使用C中的格式化输入就好了,结果搞了两个小时才搞定,心情郁闷可想而知)

//int  test[4];



//test[0] = 0;

//file>>dec>>test[0];

//groundtruth_rect[i].x = test[0];



//test[1] = 0;

//file.seekg(1,ios::cur);

//file>>dec>>test[1];

//groundtruth_rect[i].y = test[1];



//test[2] = 0;

//file.seekg(1,ios::cur);

//file>>dec>>test[2];

//groundtruth_rect[i].width = test[2];



//test[3] = 0;

//file.seekg(1,ios::cur);

//file>>dec>>test[3];

//groundtruth_rect[i].height = test[3];
//file.seekg(1,ios::cur);


采用的方法是运算符>>,中间的dec是表示采用十进制的方式输入,插入器(>>)+操纵符(dec)的方式,刚开始并没有加file.seekg(1,ios::cur);进行文件的重定位,除了第一个之外后面读到的数据全是0,我就这样一步一步的通过调试(不太熟悉这个机制,又急着实现,只能盲人摸象了)。后来采用了file.seekg(1,ios::cur);来对文件的读位置进行定位,跳过了格式化作用的逗号,就这样才能正确的读入了。结果开始运行后,发现一共500多个矩形框的数据,这种方式只能读取到221个,而且读出的数据是对的,但是后面的200多个就不知道为啥读不进来了。这个bugger也依然没有解决(希望有高人指点迷津)!

有了以上的调试经历,我感觉到不能再盲人摸象,便决定对C++的典型文件操作进行一下学习和总结:

具体内容可以参看了别人的博文,我下面只对比较常用的内容进行介绍:http://blog.csdn.net/jiangxinyu/article/details/7875931 和 http://www.cnblogs.com/kzloser/archive/2012/07/16/2593133.html
不管是Linux(shell)还是windows下,一般默认打开的输入输出设备对象都会有三种:一是标准输入设备键盘缓冲区,二是标准输出设备显示器缓冲区,三是错误信息。(特别是在linux下的shell命令,很经典的对照,有兴趣的可以了解一下,输入输出重定向的方法是不是类似c++中的iostream与fstream,ofstream,ifstream)。

当然首先就是打开文件,一般都会有文本文件和二进制文件的选项,默认大都是文本文件,C语言中的“wb+” b表示为二进制,而C++中为ios::binary
C++有
操纵符 功能 输入/输出

dec 格式化为十进制数值数据 输入和输出

endl 输出一个换行符并刷新此流 输出

ends 输出一个空字符 输出

hex 格式化为十六进制数值数据 输入和输出

oct 格式化为八进制数值数据 输入和输出

setpxecision(int p) 设置浮点数的精度位数 输出
对应到C中有格式化的输入输出:%c,%d,%f,%s等等。

另外与C的文件操作方式不太一样的地方是C++管理读指针和写指针,分别可以利用seekg和seekp来设定
ios::beg:  文件开头

ios::cur:  文件当前位置

ios::end:  文件结尾
而对应到C则是fseek(),ftell等。
C的文件操作总结如下:


C++经典的文件操作如下:



*******************************************************************************************************************************************************************************************************2015-7-24

C/C++文件操作经验总结的更多相关文章

  1. Mapreduce的文件和hbase共同输入

    Mapreduce的文件和hbase共同输入 package duogemap;   import java.io.IOException;   import org.apache.hadoop.co ...

  2. mapreduce多文件输出的两方法

    mapreduce多文件输出的两方法   package duogemap;   import java.io.IOException;   import org.apache.hadoop.conf ...

  3. 01.SQLServer性能优化之----强大的文件组----分盘存储

    汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 文章内容皆自己的理解,如有不足之处欢迎指正~谢谢 前天有学弟问逆天:“逆天,有没有一种方 ...

  4. SQL Server 大数据搬迁之文件组备份还原实战

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 解决方案(Solution) 搬迁步骤(Procedure) 搬迁脚本(SQL Codes) ...

  5. SQLSERVER将一个文件组的数据移动到另一个文件组

    SQLSERVER将一个文件组的数据移动到另一个文件组 有经验的大侠可以直接忽视这篇文章~ 这个问题有经验的人都知道怎麽做,因为我们公司的数据量不大没有这个需求,也不知道怎麽做实验 今天求助了QQ群里 ...

  6. SQL Server中的高可用性(2)----文件与文件组

        在谈到SQL Server的高可用性之前,我们首先要谈一谈单实例的高可用性.在单实例的高可用性中,不可忽略的就是文件和文件组的高可用性.SQL Server允许在某些文件损坏或离线的情况下,允 ...

  7. C# ini文件操作【源码下载】

    介绍C#如何对ini文件进行读写操作,C#可以通过调用[kernel32.dll]文件中的 WritePrivateProfileString()和GetPrivateProfileString()函 ...

  8. 【小程序分享篇 一 】开发了个JAVA小程序, 用于清除内存卡或者U盘里的垃圾文件非常有用

    有一种场景, 手机内存卡空间被用光了,但又不知道哪个文件占用了太大,一个个文件夹去找又太麻烦,所以我开发了个小程序把手机所有文件(包括路径下所有层次子文件夹下的文件)进行一个排序,这样你就可以找出哪个 ...

  9. 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新

    上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...

随机推荐

  1. Webstorm 2019最新激活码

    Webstorm 2019激活码(有效期至2020年6月5日)   K6IXATEF43-eyJsaWNlbnNlSWQiOiJLNklYQVRFRjQzIiwibGljZW5zZWVOYW1lIjo ...

  2. 洛谷 P1855 榨取kkksc03 题解

    P1855 榨取kkksc03 题目描述 洛谷2的团队功能是其他任何oj和工具难以达到的.借助洛谷强大的服务器资源,任何学校都可以在洛谷上零成本的搭建oj并高效率的完成训练计划. 为什么说是搭建oj呢 ...

  3. ArcGIS Pro 性能诊断

    是否遇到过 ArcGIS Pro 显示地图很慢很卡的情况呢? 我们可以通过以下步骤来诊断和调整. 调用方法:点击当前展示缓慢的面板(可以是地图视图也可以是三维场景视图),按下键盘 Shift+E.这时 ...

  4. 如何快速把ps序列图层建立帧动画?

    工具ps 1.将序列帧图片载入ps 新建->脚本->将文件载入堆栈 2.制作序列帧动画 窗口->时间轴->时间轴面板右上角菜单->从图层建立帧 3.去除多余的透明画布 全 ...

  5. linux shell下面的几种proxy方式

    设置ALL_PROXY环境变量 export ALL_PROXY=socks5://127.0.0.1:1080 支持socks5 http https 取消 export ALL_PROXY=&qu ...

  6. php 数组元素加法

    <?php//添加一个元素 $dirs[] = '1location';//再次添加一个元素 $dirs[] = '2location';//第三次添加一个元素 $dirs[] = '3loca ...

  7. HTML meta pragma no-cache 页面缓存

    HTML meta pragma no-cache 页面缓存不缓存页面(为了提高速度一些浏览器会缓存浏览者浏览过的页面,通过下面的定义,浏览器一般不会缓存页面,而且浏览器无法脱机浏览.) <me ...

  8. eclipse快捷键及设置【转】

    1.Eclipse设置新建菜单初始项 windows-->Perspective-->Customize Perspective--> 2.Eclipse快捷键 1. ctrl+sh ...

  9. docker run 参数含义

    -a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项: -d: 后台运行容器,并返回容器ID: -i: 以交互模式运行容器,通常与 -t 同时使用:     ...

  10. 反手来个K8S入门到跑路

    layout: post title: 反手来个K8S入门到跑路 category: linux date: 2019-06-09 tags: linux k8s 反手来个K8S入门到跑路 前言 放假 ...