一个很诡异的C++问题 关于include fstreamm.getline()

1065人阅读
关于助教在上课的时候用于读取文件内容的getLine方法,
在今天经过一个小程序试验得到这样的结果,
但是至今不懂得为什么,先记录下来之后再去找答案
1.读取文件test中行的内容,代码是下所示
#include &iostream&
#include&fstream&
int main(){
char name[]=&test.txt&;
fstream fs(name,ios::in);
char content[10];
if(fs.is_open()){
while(!fs.eof()){//此处为错误
fs.getline(content,10);
cout&&content&&
而test.txt中的内容为
!!!!!!!!!!!!!!问题:
其中内容从第2行开始就超过了10个字符的长度,然后从读取完第二次后,发现进行读取时,content中的内容没有变化,也就是说读取失败?这是为什么?而且这样while循环条件 !fs.eof()一直是成立的,为什么?
2.下面是同一个程序,将content的长度改变,getLine()方法的参数也改变成25,代码如下
#include &iostream&
#include&fstream&
int main(){
char name[]=&test.txt&;
fstream fs(name,ios::in);
char content[25];
if(fs.is_open()){
while(!fs.eof()){
fs.getline(content,25);
cout&&content&&
此处content内容能够正确打印,且正确退出循环
3.在写一个小程序的时候还出现过这个问题:后面发现char content[20],而fs.getLine(content,30);然后出现了这个...后面想想个那个函数的调用压栈有关系吧,就是可能把返回地址给覆盖了?【好吧,真的不懂。。。以后过来修改解释】
虽然还是有问题不会,但是还是有些收获的。
在使用fstream的getLine()方法时,参数一定要大于一行储存的最长字符长度,否则会失败;若是getLine的参数大于字符个数,那么程序运行读取content完毕后,会在数组的末尾自动加上'\0';而且根据助教的写法,while成立的条件为fs.getLine(content,25),感觉起来安全很多,至少不会因为读取一次错误造成一直在循环...
ps:要是哪位看到了这个,能够解释我的疑问的话,欢迎指教。。。3Q
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:6694次
排名:千里之外
原创:13篇
(1)(1)(2)(2)(2)(3)(1)(1)c++ fstream + string 处理大数据 - 推酷
c++ fstream + string 处理大数据
(1)之前处理文本数据时,各种清洗数据用的都是java的File,FileReader/FileWriter,BufferedReader/BufferedWriter等类,
(2)应用java的原因是java里面的map非常灵活,eclipse编译器更是给力,而且ctrl 可以追踪函数 等,
(3)应用java的另一个原因是java里面的string类的字符串处理非常灵活,各种函数是应用尽有。
(4)上面两点算是自己的误解吧,因为c++里面也有也有与之对应的 fstream类, &c++map容器类,
(5)c++里面也有相对比较成熟的string类,里面的函数也大部分很灵活,没有的也可以很容易的实现split,strim等,
(6)最近从网上,看到了一句很经典的话,c++的风fstream类 + string类 也可以非常好的处理文本文件,让我们一起来见证
二:fstream的前世今生
包含的头文件 & &#include &fstream& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &&
C++中的三个文件流 & & & & & & & & & & & & & & & & & & & & & & & & & & & & &
a ---- ofstream ofs(&文件名&, 打开方式); & & & & & & & &b ---- ifstream ifs(&文件名&, 打开方式); & & c ---- fstream fs(&文件名&,输入打开方式 | 输出打开方式); & 三种文件 & & &流分别用于写文件、读文件、读写文件 ,一般用a b两种方式进行,因为一个文件同时进行读写的情况采用c 方式。
三种文件流都可先定义,再打开文件,以fstream为例 & & & & & & & & & & & & & &
& & & & fs.open(&文件名&, 输入打开方式 | 输出打开方式); & & & & & & & & & & & & & &
其中“打开方式”可以不给出。 & & 若不给出,对于oftream默认为ios::out,iftream默认为ios::in&
(2)文件打开函数
在C++中,对文件的操作是通过stream的子类fstream(file stream)来实现的,所以,要用这种方式操作文件,就必须加入头文件fstream.h。下面就把此类的文件操作过程一一道来。
打开文件在fstream类中,有一个成员函数open(),就是用来打开文件的,其原型是:
filename: & & 要打开的文件名
mode: & & & & 要打开文件的方式
access: & & & 打开文件的属性
(3)打开方式 & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &&
ios::out 输出数据覆盖现有文件 (默认的写代开方式,文件不存在,创建之;若存在,则覆盖原来的内容)
ios::ate 打开文件并移动文件指针至末尾 & & & & & & & & & & & & & & & & & &&
& &ios::in & & 打开文件以输入 (默认读的打开方式)&
ios::trunc & 输出文件中现有内容(ios::out的默认操作) & & & & & & & & & & & &&
ios::binary 二进制打开供读写
(4)文件指针定位
和C的文件操作方式不同的是,C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时,相应的指针自动变化。所以,C++的文件定位分为读位置和写位置的定位,
对应的成员函数是 seekg()和seekp(),seekg()是设置读位置,seekp是设置写位置。它们最通用的形式如下:&
istream &seekg(streamoff offset,seek_dir origin);&
ostream &seekp(streamoff offset,seek_dir origin);&
streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值,seek_dir 表示移动的基准位置,是一个有以下值的枚举:
ios::beg: 文件开头&
ios::cur: 文件当前位置&
ios::end: 文件结尾&
这两个函数一般用于二进制文件,因为文本文件会因为系统对字符的解释而可能与预想的值不同。&
file1.seekg(1234,ios::cur);//把文件的读指针从当前位置向后移1234个字节
file2.seekp(1234,ios::beg);//把文件的写指针从文件开头向后移1234个字节
注意:一个汉字是占用两个字节的,一个字母占用一个字节。
(5)fstream ,ifstream,ofstream,ostream等的关系
三:实战篇
(1)no write
//读取方式: 逐词读取, 词之间用空格区分(遇到空格认为本次读取结束),输出之后进行下一次读取
//read data from the file, Word By Word
//when used in this manner, we'll get space-delimited bits of text from the file
//but all of the whitespace that separated words (including newlines) was lost.
void ReadDataFromFileWBW()
ifstream fin(&data.txt&);
cout && &*****start*******& &&
while( fin && s )
cout && &Read from file: & && s &&
cout && &*****over*******& &&
(2)read by line &fin.getline(char*,n)
//读取方式: 逐行读取, 将行读入字符数组, 行之间用回车换行区分
//If we were interested in preserving whitespace,
//we could read the file in Line-By-Line using the I/O getline() function.
void ReadDataFromFileLBLIntoCharArray()
ifstream fin(&data.txt&,ios::in);// 默认的打开模式就是ios::in
ofstream fout(&out.txt&,ios::out);// 默认代开模式就是ios::out
const int LINE_LENGTH = 100;
char str[LINE_LENGTH];
fout && &****CharArray start******& &&
cout && &****CharArray start******& &&
fin.seekg(-20,ios::end);// -20表示从end向前移动20字节,汉字占两字节;20表示向后移动指针
while( fin.getline(str,LINE_LENGTH) )
fout && str &&
cout && &Read from file: & && str && &...& &&// ****str里面本身包含着换行的,原来是什么样子,现在保存的就是什么样子
fout && &*****over*******& &&
cout && &*****over*******& &&
(3) read by line fin.getline(fin,string)
//读取方式: 逐行读取, 将行读入字符串, 行之间用回车换行区分
//If you want to avoid reading into character arrays,
//you can use the C++ string getline() function to read lines into strings
void ReadDataFromFileLBLIntoString()
ifstream fin(&data.txt&,ios::in);// 默认的打开模式就是ios::in
ofstream fout(&out.txt&,ios::app);// 追加到文件尾的方式打开
cout && &****start******& &&
while( getline(fin,s) )
fout && s &&// ofstream是默认,若文件不存在,则先建立此文件,并且再向文件写的过程中换行已经不存在了,这与cout控制台输出一样哦。。。
cout && &Read from file: & && s &&//****s同str里面本身已经没有了换行的,这和原来的getline()函数是一样的;数据原来是什么样子,现在保存的就是什么样子
fout && &*****over*******& &&
cout && &*****over*******& &&
fout.close();
(4) main函数
#include &iostream&
#include &fstream&
#include &string&
#include &cstdlib&// exit()函数
//输出空行
void OutPutAnEmptyLine()
cout&&&\n&;
//带错误检测的读取方式
//Simply evaluating an I/O object in a boolean context will return false
//if any errors have occurred
void ReadDataWithErrChecking()
string filename = &dataFUNNY.txt&;
ifstream fin( filename.c_str());
if( !fin )
cout && &Error opening & && filename && & for input& &&
int main()
ReadDataFromFileWBW(); //逐词读入字符串
OutPutAnEmptyLine(); //输出空行
ReadDataFromFileLBLIntoCharArray(); //逐词读入字符数组
OutPutAnEmptyLine(); //输出空行
ReadDataFromFileLBLIntoString(); //逐词读入字符串
OutPutAnEmptyLine(); //输出空行
ReadDataWithErrChecking(); //带检测的读取
data文本文件的数据格式
(插入c 与 c++文件处理对比)
&p&#include &iostream&
#include &fstream&
#include &cassert&
#include &ctime&
#include &cstdio&
&/p&&p&void test_read()
const char* read_file = &D:\\zyp\\大数据实验&a target=_blank href=&file://\\TOKEN_ENEX_W_yuansi.csv&&\\TOKEN_ENEX_W_yuansi.csv&/a&&;
const int BUF_SIZE = 1024 ;
char buf[BUF_SIZE];
//c++ style writing file
ifstream ifs(read_file,ios::binary);
assert(ifs);
time_t start,
while(!ifs.eof())
ifs.read(buf,BUF_SIZE);
end = clock();
ifs.close();
cout&&&C++ style: &&&end - start &&& ms&&&
//c style writing file
FILE* fp = fopen(read_file, &rb&);
int len = 0;
char *pline = NULL;
//len = fread(buf,1,BUF_SIZE,fp);
pline = fgets(buf,BUF_SIZE,fp);
cout && buf &&
//cout&&len&&
}while(pline != NULL);
end = clock();
fclose(fp);
cout&&&C style: &&&end - start &&& ms&&&
cin.get();
int main()
test_read();
}&/p&总之,/fread() 的效率 是 ifstream.read()的将近十倍!但是,fstream 对于处理数据而言,还是统一的应用STL的标准好;总之,语言仅仅是一门工具,本身没有优劣之分。fgets(char*,int,File*); getline(stream,string),还是个人习惯的好。如今,还是建议应用面向对象的语言好一些,java 或者 c++,java更加强大一些,有自己的各种类库。c++没有的,链接JDBC的东东的
第一条,(写了这么多了,用两句话概括吧)最近从网上,看到了一句很经典的话,c++的风fstream类 + string类 也可以非常好的处理文本文件;
第二条,语言仅仅是一种工具,本身并没有优劣之分
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致getline用法_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
getline用法
上传于||文档简介
&&一些简单的方法
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩2页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢ifstream中getline读入过长数据后处于fail状态如何恢复 - C++当前位置:& &&&ifstream中getline读入过长数据后处于fail状态如何ifstream中getline读入过长数据后处于fail状态如何恢复&&网友分享于:&&浏览:44次ifstream中getline读入过长数据后处于fail状态怎么恢复char buff[200];tmpfile.open(&C:\\test.txt&, ios::in);while( !tmpfile.eof() ){ &
tmpfile.getline(buff, sizeof(buff)); &
cout &&}C:\test.txt是一篇文章,其中有一段文字超过200byte,getline可以将200byte以前的内容读入buff中,但在这之后io流的fail标志位变为1,其余标志位全部变成0,io流不响应读取操作,循环也无法结束。当遇到这种状况时,我想让其恢复good状态并继续从200byte之后读取数据,请问可以吗?应该怎么做?------解决方案--------------------flush 或者 clear
------解决方案--------------------
好像不行,我推荐你一个好的办法,用string 类:C/C++ code
#include &iostream&
#include &fstream&
#include &string&
int main()
string strB
tmpfile.open(&C:\\test.txt&, ios::in);
while( !tmpfile.eof() )
getline(tmpfile, strBuff);
cout &&strBuff&&
------解决方案--------------------tmpfile.clear()
------解决方案--------------------C/C++ code
while(getline(tempFile,str))
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有

我要回帖

更多关于 include fstream 的文章

 

随机推荐