最近在做一个从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. PHP的3种发送HTTP请求的方式

    1.CURL方式发送数据及上传文件 <?php class IndexController extends ControllerBase { public function indexActio ...

  2. Problem 1 bfs+set

    $des$ 小G有一个长度为 $n$ 的 01 串 T ,其中只有 $T_S = 1$,其余位置都是 $0$.现在小G可以进行若干次以下操作:选择一个长度为 $K$ 的连续子串(K是给定的常数),翻转 ...

  3. CODE FESTIVAL 2017 Final题解

    传送门 \(A\) 咕咕 const int N=55; const char to[]={"AKIHABARA"}; char s[N];int n; int main(){ s ...

  4. Day15:大前端

    垂直水平居中 css: display: table-cell; text-align: center; vertical-align: middle; div: display: inline-bl ...

  5. 让img图片像背景一样显示

    如何让图片像背景一样显示呢? 这里需要用到object-fit属性 MDN地址:https://developer.mozilla.org/zh-CN/docs/Web/CSS/object-fit ...

  6. 第12组 Alpha冲刺(2/6)

    Header 队名:To Be Done 组长博客 作业博客 团队项目进行情况 燃尽图(组内共享) 展示Git当日代码/文档签入记录(组内共享) 注: 由于GitHub的免费范围内对多人开发存在较多限 ...

  7. python中string、json、bytes的转换

    json->string str = json.dumps(jsonobj) bytes->string str = str(bytes,‘utf-8’) string->json ...

  8. pymongo错误记录

    1.AutoReconnect pymongo.errors.AutoReconnect: connection closed 2.ServerSelectionTimeoutError pymong ...

  9. 【软工实践】团队项目Snug-需求分析报告

    组长博客链接 博客链接 团队项目整体计划安排 阶段序列 阶段时间 主要阶段任务 完成情况 第一阶段 9.6 团队成立 已完成 第二阶段 9.6-9.13 课题选择 已完成 第三阶段 9.13-9.18 ...

  10. T-MAX组--项目冲刺(第七天)

    THE SEVENTH DAY 项目相关 作业相关 具体描述 所属班级 2019秋福大软件工程实践Z班 作业要求 团队作业第五次-项目冲刺 作业正文 T-MAX组--项目冲刺(第七天) 团队名称 T- ...