C++为啥不能在ifstream读取整个文件文件中判断减号字符?

C++中,利用ifstream从文件中读出数据,是不是会自动舍去空格?_百度知道
C++中,利用ifstream从文件中读出数据,是不是会自动舍去空格?
具体说编写面语句ifstream fin(&a.txt&); ofstream fout(&b.txt&);
while(fin&&c){ fout&&c; } 执行a.txt内容比说a b c d e字母间都空格输b.txt变abcde空格都没ifstream自舍空格办通修改面语句解决问题
提问者采纳
能fin&&c句理解误每输入流读取字符串字符串间由换行符空格或者制表符割所例读取a遇空格截断输a再往读遇b空格截断输b类推按说自舍空格若要修改试试用readline()函数读取行:string s = fin.readline().
我用的是VC6.0,readline()好像无法使用啊,我主要是希望单词间的空格别被舍去,比如说别让I love you在处理后变成了Iloveyou,请问还有什么能是在VC中改进这一问题的方法吗?
#include&iostream&#include&fstream&#include&string&int main(){ ifstream fin(&a.txt&);
ofstream fout(&b.txt&);
char* c = new char[100];
fin.getline(c,100); fout&&c; return 0;} 你试试。
提问者评价
恩,谢谢了
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁一 C++中流的概念在程序设计中,数据输入/输出(I/O)操作是必不可少的,C++语言的数据输入/输出操作是通过I/O流库来实现的。C++中把数据之间的传输操作称为流,流既可以表示数据从内存传送到某个载体或设备中,即输出流,也可以表示数据从某个载体或设备传送到内存缓冲区变量中,即输入流。C++流涉及以下概念:标准I/O流:内存与标准输入输出设备之间信息的传递;文件I/O流:内存与外部文件之间信息的传递;字符串I/O流:内存变量与表示字符串流的字符数组之间信息的传递STL中定义的流类:流类分类流类名称流 类 作 用流基类ios所有流类的父类,保存流的状态并处理错误输入流类istream输入流基类,将流缓冲区中的数据作格式化和非格式化之间的转换并输入ifstream文件输入流类istream_withassigncin输入流类,即操作符&&输入流istrstream串输入流类, 基于C类型字符串char*编写istringstream串输入流类, 基于std::string编写输出流类ostream输出流基类,将流缓冲区中的数据作格式化和非格式化之间的转换。并输出ofstream文件输出流类ostream_withassignCout、cerr、clog的输出流类,即操作符&&输出流ostrstream串输入流类, 基于C类型字符串char*编写ostringstream串输入流类, 基于std::string编写输入/输出流类iostream多目的输入/输出流类的基类fstream文件流输入/输出类strstream串流输入/输出类, 基于C类型字符串char*编写stringstream串流输入/输出类, 基于std::string编写注,对于串流,提供了两套类,一个基于C类型字符串char *编写(定义于头文件strstream),一个基于std::string编写(定义于sstream), 后者是C++标准委员会推荐使用的。二 C++中读取string对象1.标准输入读取:cin && stringa.忽略开头所有的空白字符(空格、换行、制表符等);b.读取字符直至再次遇到空白字符,读取终止;2.读取整行文本:getline(istream, string)a.不忽略开头的空白字符;b.读取字符直至遇到换行符,如果第一个字符是换行符,则返回空string;c.返回时丢弃换行符,换行符不存储在string中。三 对sstream(经常用作格式转换)库的讲解使用stringstream对象简化类型转换如果你已习惯了&stdio.h&风格的转换,也许你首先会问:为什么要花额外的精力来学习基于&sstream&的类型转换呢?也许对下面一个简单的例子的回顾能够说服你。假设你想用sprintf()函数将一个变量从int类型转换到字符串类型。为了正确地完成这个任务,你必须确保证目标缓冲区有足够大空间以容纳转换完的字符串。此外,还必须使用正确的格式化符。如果使用了不正确的格式化符,会导致非预知的后果。下面是一个例子:int n=10000;char s[10];sprintf(s,”%d”,n);// s中的内容为“10000”到目前为止看起来还不错。但是,对上面代码的一个微小的改变就会使程序崩溃:int n=10000;char s[10];sprintf(s,”%f”,n);// 看!错误的格式化符在这种情况下,程序员错误地使用了%f格式化符来替代了%d。因此,s在调用完sprintf()后包含了一个不确定的字符串。要是能自动推导出正确的类型,那不是更好吗?进入stringstream由于n和s的类型在编译期就确定了,所以编译器拥有足够的信息来判断需要哪些转换。&sstream&库中声明的标准类就利用了这一点,自动选择所必需的转换。而且,转换结果保存在stringstream对象的内部缓冲中。你不必担心缓冲区溢出,因为这些对象会根据需要自动分配存储空间。注意,&sstream&使用string对象来代替字符数组。这样可以避免缓冲区溢出的危险。而且,传入参数和目标对象的类型被自动推导出来,即使使用了不正确的格式化符也没有危险。string到int的转换string result=”10000”;int n=0;stream&&stream&&n;//n等于10000复利用stringstream对象如果你打算在多次转换中使用同一个stringstream对象,记住再每次转换前要使用clear()方法;在多次转换中重复使用同一个stringstream(而不是每次都创建一个新的对象)对象最大的好处在于效率。stringstream对象的构造和析构函数通常是非常耗费CPU时间的。在类型转换中使用模板你可以轻松地定义函数模板来将一个任意的类型转换到特定的目标类型。例如,需要将各种数字值,如int、long、double等等转换成字符串,要使用以一个string类型和一个任意值t为参数的to_string()函数。to_string()函数将t转换为字符串并写入result中。使用str()成员函数来获取流内部缓冲的一份拷贝:template&class T&void to_string(string & result,const T& t){//创建一个流oss&&t;//把值传递如流中result=oss.str();//获取转换后的字符转并将其写入result}这样,你就可以轻松地将多种数值转换成字符串了:to_string(s1,10.5);//double到stringto_string(s2,123);//int到stringto_string(s3,true);//bool到string可以更进一步定义一个通用的转换模板,用于任意类型之间的转换。函数模板convert()含有两个模板参数out_type和in_value,功能是将in_value值转换成out_type类型:template&class out_type,class in_value&out_type convert(const in_value & t){stream&&t;//向流中传值out_//这里存储转换结果stream&&//向result中写入值}这样使用convert():string s=”12.56”;d=convert&double&(s);//d等于12.56salary=convert&string&(9000.0);//salary等于”9000”stringstream通常是用来做数据转换的。相比c库的转换,它更加安全,自动和直接。四&STL C++中string、ifstream、stringstream的使用1、从标准输入接受字符串,然后进行相关处理#include&iostream&#include&sstream&&#include&string&&&int main()&{& //定义一个stirng对象,从标准输入接受一个字符串&cout&&&请输入一行字符串:&&&&getline(cin,s);&stringstream ss(s); //定义一个string流(使用s实例化)&cout&&&处理后的字符串为:&&& //将string流里的东西输出&for(string s1;ss&&s1;cout&&s1&&endl);&return 0;&}运行结果如下:请输入一行字符串:you are a good boy&处理后的字符串为:&you&are&a&good&boy根据前文所说“忽略开头空白字符,读取字符直至再次遇到空白字符为止”,这样的结果不难理解。getline函数原型如下:template&class E, class T, class A&
basic_istream&E, T&& getline( basic_istream &E, T&& is,
basic_string&E, T, A&& str);
template&class E, class T, class A&
basic_istream&E, T&& getline(
basic_istream &E, T&& is,
basic_string&E, T, A&& str,
E delim);第二个重载函数很有意思,结尾是char, 或wchar型的一个分隔符,如果设为’/n’,则为以换行符为分隔,如果设为’,',则为以逗号为分隔。由此,虽然C++中的字符串没有分割函数,如果是从文件中读取出被特定分隔符分隔的文本,那么就可以用此方法,如:std::file.open(&tt.txt&);&std::string s,t;&while(std::getline(file,s)) //按行读取&{&std::stringstream strs(s); //把行装到另一个流中&while(std::getline(strs,t,’,')) //把流按分隔符实现分割&std::cout&&t&&std::&}&file.close();上面的程序相当于将整个文本先按行分割,再按分隔符分割,也可以变换一下,只按分隔符分割,然后过滤掉按行符,换行符与某元素连在了一起,并处于开头。五&C++的流操作复制文件写.wrl, .obj文件格式转换时用到,记录一下相关方法使用C++标准程序库的输入输出流(I/O Stream)复制文件,存在许多的方法,方法一:逐个字符复制#include & fstream &std::ifstream input(&in&,ios::binary);&std::ofstream output(&out&,ios::binary);&&while (input.get(ch)) output &&注意:如果使用input&&ch读取字符,则必须先调用input.unsetf(ios::skipws)取消输入流默认的跳过空白符(空格、换行、制表符等)的输入格式,因为换行符是空白符的一种。另外,对于ofstream对象,默认的操作方式是ios_base::out | ios_base::trunc,即输出和文件清空!方法二:逐行复制#include & fstream &#include & string &&std::ifstream input(&in&,ios::binary);&std::ofstream output(&out&,ios::binary);&std::&while (getline(input,line)) output && line && &/n&;注意:这里的代码有一个小小的缺陷,如果文件不是纯文本格式的文件,或者文本文件的最后没有换行符,那么会导致复制后的文件末尾添加了一个多余的换行符。方法三:迭代器复制#include & fstream &#include & iterator &&#include & algorithm &&std::ifstream input(&in&,ios::binary);&std::ofstream output(&out&,ios::binary);&input.unsetf(ios::skipws);&copy(istream_iterator(input),istream_iterator(),ostream_iterator(output,&&));同样这里也有一个小技巧,输入流的格式默认为跳过空白字符,因此调用unsetf取消这个格式,才可保证正确的复制。见后方中字符串缓冲与文件缓冲类的定义,文件缓冲类没有定义自己的迭代器,所以就用了方法四:缓冲区复制#include & fstream &std::ifstream input(&in&,ios::binary);&std::ofstream output(&out&,ios::binary);&output && input.rdbuf();这里直接使用了输入流的缓冲区,因此没有引入额外的临时对象。很显然,上述四种方法中,最后一种方法最简洁,由于直接操作输入流的缓冲区,从运行效率上来说,也比其他方法有着略微的优势(当然,由于操作系统可能提供了 额外的基于设备的文件缓冲机制,也许你无法证实这一点)。因此,除非要对输入内容进行处理,直接复制文件推荐最后一种方法,既不容易出错,又能获得良好的性能。另外,对文件进行更改、删除、插入等操作,可以直接用以上方法也可以先把文件读入vector&string&,处理后再输出,不过当文件很大的时候,vector占用内存空间较大,而且输出时会破坏原文件格式,尽量不使用。以上是几种同种流(文件流)之间的数据复制的方式,字符串流与文件流之间也可以以此方式进行复制。另外,再看一下get函数:int_type get();
basic_istream& get(E& c);
basic_istream& get(E *s, streamsize n);
basic_istream& get(E *s, streamsize n, E delim);
basic_istream& get(basic_streambuf&E, T& *sb);
basic_istream& get(basic_streambuf&E, T& *sb, E delim);delim表示结束符,前文中讨论的流分割函数还记得吧?又多了种方法,估计get与全局函数getline(不是那个成员函数,成员函数要求给出streamsize,而全局的就不用)实现得差不多。默认的也是’/n’,按行分隔。C++流缓冲区的应用——输出文件内容的方法举例简单讨论C++流对象的底层缓冲区,并举例介绍如何使用该缓冲区进行文件内容的输出C++标准库封装了一个缓冲区类streambuf,以供输入输出流对象使用。每个标准C++输出输出流对象都包含一个指向streambuf的指针,用户可以通过调用rdbuf()成员函数获得该指针,从而直接访问底层streambuf对象。因此,可以直接对底层缓冲区进行数据读写,从而跳过上层的格式化输入输出操作。template &class Elem, class Traits& class basic_ios: public ios_base {&basic_streambuf&_Elem, _Traits&*_M&//C++标准库封装了一个缓冲区类streambuf。&_Mysb * rdbuf() const&{ // return stream buffer pointer&return (_Mystrbuf);&}&//使调用者与参数(流缓冲指针)关联,&//返回自己当前关联的流缓冲区指针, 可用来重定向等&_Mysb * rdbuf(_Mysb *_Strbuf)&{ // set stream buffer pointer&_Mysb *_Oldstrbuf = _M&_Mystrbuf = _S&return (_Oldstrbuf);&}&};对象通过调用rdbuf()获得了底层streambuf对象的指针,也就可以通过该指针调用streambuf支持你各种操作进行输入输出。在这里主要介绍如何利用该指针实现文件内容的输出。对于文件流类和字符串流类,分别派生了相应的流缓冲区类型:template&class _Elem,class _Traits& class&basic_streambuf; typedef basic_streambuf&char, char_traits&char& &&streambuf; typedef basic_streambuf&wchar_t, char_traits&wchar_t& &&wstreambuf;&template &class Elem, class Tr = char_traits&Elem&, class Alloc = allocator&Elem& & class&basic_stringbuf:&public basic_streambuf&Elem, Tr&&typedef basic_stringbuf&char, char_traits&char&, allocator&char& &&stringbuf; typedef basic_stringbuf&wchar_t, char_traits&wchar_t&, allocator&wchar_t& &&wstringbuf;&template &class Elem, class Tr = char_traits&Elem& & class&basic_filebuf: public basic_streambuf&Elem, Tr&&typedef basic_filebuf&char, char_traits&char& &&filebuf;&typedef basic_filebuf&wchar_t, char_traits&wchar_t& &&wfilebuf;输出流提供了一个重载版本operator&&,它以streambuf指针为参数,实现把streambuf对象中的所有字符输出到输出流出中;输入流也提供了一个对应的operator&&重载版本,把输入流对象中的所有字符输入到streambuf对象中。输入流的get成员重载版本中还有以streambuf指针为参数的版本,也可以用来把输入流的东西写入到输出流缓冲区中。下面用三种方法实现把一个文件的内容输出标准输出(当然还可以通过普通的标准格式化输入输出完成):方法一:通过operator&&#include &iostream&
#include &fstream&
int main()
ifstream fin(&source.dat&);
cout&&fin.rdbuf(); return 0;
}方法二:利用get成员函数ifstream fin(&source.dat&);
while (!fin.get(*cout.rdbuf()).eof()) { // extract a line input
if (fin.fail()) // blank line
fin.clear();
cout&&char(fin.get()); // extract '/n'
}代码解释:由于上面代码中的get版本在遇到’/n’字符时,结束提取,所以需要用循环实现整个文件内容的输出。另外,当此版本get函数遇到空行时,因为没有提取到任何字符(注意:get不提取回车符),注意会设置失败标志ios::failbit,所以此时应当调用clear()函数清除错误标志。同样,因为该版本get不会提取回车符,所以需要用另一版本的get()提取回车符。不同版本的Get函数参见前文。此处还使用了*cout.rdbuf(),cout是ostream类的对象,当然就有缓冲区,可以用rdbuf返回缓冲区对象的指针。最后,关于fin.clear, 需要特别注意的是:要清空流类对象的内存,不能用clear方法,那只是设置了错误标志位;方法三:利用重载的get函数ifstream fin(&main.cpp&);
fin.get(*cout.rdbuf(), EOF);代码解释:这个版本的get成员函数可以自定义提取终止符。这里通过设置为文件结束符(EOF)来达到一下提取整个文件的目的。当然,你可以把上面的cout换成任意的输出流,比如文件输出流,从而可以实现文件的拷贝功能。另外,上面代码中并没有使用输入流的&&操作符,因为&&和&&是相对的,只是把操作数交换一下位置罢了。因此,你可以把上面代码中用out&&in.rdbuf()的地方换成in&&out.rdbuf(),代码的功能完全一样,效果也一样。六 关于缓冲区1.缓冲类型。标准库提供缓冲是为了减少对read和write的调用。提供的缓冲有三种类型(整理自APUE):全缓冲。 在这种情况下,实际的I/O操作只有在缓冲区被填满了之后才会进行。对驻留在磁盘上的文件的操作一般是有标准I/O库提供全缓冲。缓冲区一般是在第一次对流进行I/O操作时,由标准I/O函数调用malloc函数分配得到的。flush描述了标准I/O缓冲的写操作。缓冲区可以由标准I/O函数自动flush(例如缓冲区满的时候);或者我们对流调用fflush函数。行缓冲。 在这种情况下,只有在输入/输出中遇到换行符的时候,才会执行实际的I/O操作。这允许我们一次写一个字符,但是只有在写完一行之后才做I/O操作。一般的,涉及到终端的流–例如标注输入(stdin)和标准输出(stdout)–是行缓冲的。无缓冲。 标准I/O库不缓存字符。需要注意的是,标准库不缓存并不意味着操作系统或者设备驱动不缓存。ISO C要求:当且仅当不涉及交互设备时,标准输入和标准输出是全缓存的。标准错误绝对不是全缓存的。但是,这并没有告诉我们当标准输入/输出在涉及交互设备时,它们是无缓存的还是行缓存的;也没有告诉我们标准错误应该是行缓存的还是无缓存的。不过,大多数实现默认的缓存类型是这样的:标准错误总是无缓存的。对于所有的其他流来说,如果它们涉及到交互设备,那么就是行缓存的;否则是全缓存的。2.改变默认缓存类型,即自定义缓冲区a. 对于C中文件操作:可以通过下面的函数改变缓存类型(摘自APUE):void setbuf(FILE *restrict fp, char *restrict buf);int setvbuf(FILE *restrict fp, char *restrict buf, int mode, size_t size);这些函数必须在流打开之后、但是未对流做任何操作之前被调用(因为每个函数都需要一个有效的文件指针作为第一个参数)。利用setbuf,可以打开或者关闭缓存。为了打开缓存,buf参数必须一个大小为BUFSIZ的缓存,BUFSIZ是定义在stdio.h中的常量。&ISO/IEC 9899&要求:BUFSIZ至少为256。如果要关闭缓存,可以将buf设成NULL。利用setvbuf,我们可以设定缓存类型。这是通过mode参数指定的。b. 对于C++中流:virtual basic_streambuf *setbuf(E *s, streamsize n);第一个参数指向自定义缓冲区空间,第二个为缓冲区大小。七 string 和stringBuffer的区别String对象建立之后不能再改变,如果经常对字符串进行各种各样的修改,那么使用String来代表字符串的话会引起很大的内存开销。StringBuffer允许修改,不是每个不同的字符串都要生成一个新的对象,两种类的对象转换十分容易。在我以前的了解中,String是一个final Class, StringBuffer不是。所以对于 String a = &yacht& ,String b = &yacht1& String c = a + 存在一个对象拷贝构造和解析的消耗问题;对于一个StringBuffer来说,StringBuffer sb = new StringBuffer();sb.append(&yacht&) ; sb.append(&yacht1&); 因为StringBuffer是一个可以实例化的类,而且它的内建机制是维护了一个capacity大小的字符数组,所以它的append操作不存在对象的消耗问题,所以我觉得如果存在String连接这种事情,StringBuffer来做会好很多。但事情并不是这么简单,看下面代码String a = &yacht1& + &yacht2& + &yacht3& + &yacht4&;StringBuffer sb = new StringBuffer(); sb.append(&yacht1&) ; sb.append(&yacht2&); sb.append(&yacht3&) ; sb.append(&yacht4&);& String a = sb.toString();如果按照我先前说的看法,红色的效率肯定比蓝色的低,但经过测试不是这样,为什么?这里,我们需要理解程序过程的两个时期,一个是编译时,一个是运行时,在编译时,编译器会对你的程序做出优化,所以红色的String a会被优化成yacht1yacht2yacht3yacht4,而蓝色的StringBuffer只会在运行时才处理。所以效率是不一样的。如果代码是这样的:S for(int i = 0; i& 100000;i++){ a += String.valueOf(i) ;}StringBuffer sb = new StringBuffer(); for(int i = 0; i& 100000;i++){ sb.append(i) ;} String a = sb.toString();&&&&&&&如果是这种情况的话,红色的效率就大大不如蓝色,区别在哪里,就在于运行时和编译时的优化问题上!前面看到有人写String和stringBudffer的区别是前者是不能改写的,后者是可以改写的我觉得说String的字符串不能改变话是不错,但是例子要举好看看下面这个简单的例子:首先,publicclassxx {publicstaticvoidmain(String[] args) { String s1 = &You are hired!&; String s2 = &You are hired!&;if(s1==s2) { System.out.println(&一个内存空间&); }else{ System.out.println(&不是一个内存空间&); } } }打印的结果是:一个内存空间这里==的意义是两个操作数是否指向同一个对象可见s2在不用new创建的情况下会自动检索到具有相同内容的内存空间中共享,那么既然s1和s2共享了同一个对象再看下面的代码publicclassxx {publicstaticvoidmain(String[] args) { String s1 = &You are hired!&; String s2 = &You are hired!&; s1 = s1.replace('h','f'); System.out.println(s1);if(s1==s2) { System.out.println(&一个内存空间&); }else{ System.out.println(&不是一个内存空间&); } } }代码结果是You are fired!不是一个内存空间可见,String中s1的内容虽然被改写,但是已经不在是原来第一次分配到的那个内存空间,也就是String类的内容能被改变,但一旦改变系统将为其分配新的内存说到与stringBuffer的区别,从根本上来说应该是stringBuffer在做字符长度变动的时候将继续使用原来的内存空间,不新分配.而String的长度一旦变动,就如上面的例子一样,其内部将分配新的内存空间.八 streambuf相关的讲解顺序访问流中的字符。如果用一个数组模拟出流,代码将是下面样子的。char sgetc() { return buff[i]; }char sbumpc(){ return buff[i++]; } 先取当前字符,然后指针移向后一个char snextc(){ return buff[++i]; } 先移动指针,然后取值逐个字符的打印出abcdefgss && &abcdefg&;streambuf *pbuf = ss.rdbuf();do{char ch = pbuf-&sgetc() ;cout &&}while(pbuf-&snextc()!=EOF);验证缓冲区在起作用,pbuf-&in_avail()返回的值在变化fs.open(&C://test.log&);streambuf *pbuf= fs.rdbuf();while(pbuf-&sgetc()!=EOF){char ch = pbuf-&sbumpc() ; //弹出一个字符cout &&streamsize size=pbuf-&in_avail(); //查询缓冲区内有效数据个数(把缓存区看做一个容器)}实现文件大小的查询,(C函数fseek,ftell)fstream filestr (&C://test.log&);streambuf * pbuf = filestr.rdbuf();size = pbuf-&pubseekoff(0,ios_base::end);设置程序员选择的任意缓冲区(C函数setvbuf)fstream ss (&C://test.log&);streambuf *pbuf = ss.rdbuf();char mybuffer [2048]={0};pbuf-&pubsetbuf(mybuffer,2048);读取出来的一个字符,可以做退回操作ch=pbuf-&sbumpc();int r = pbuf-&sputbackc (ch);ch = pbuf-&sgetc();九 C++中控制文件读写位置如果要在输出流中加入格式控制符则要加载头文件:#include &iomanip&这里面iomanip的作用比较多:主要是对cin,cout之类的一些操纵运算子,比如setfill,setw,setbase,setprecision等等。它是I/O流控制头文件,就像C里面的格式化输出一样.以下是一些常见的控制函数的:dec置基数为10相当于&%d&hex置基数为16相当于&%X&oct置基数为8相当于&%o&&&&&&&//作用永久sample:cout&&12&&hex&&12&&oct&&12&&12;output 12c1414setprecision(n)设显示小数精度为n位//作用永久sample:setf(ios:fixed);cout&&setprecision(2)&&2.345&& ouput 2.34 //注意先用setf(ios::fixed);否则结果自己测试下&&&&&&&setw(n)设域宽为n个字符//作用临时这个控制符的意思是保证输出宽度为n。如:cout&&setw(3)&&1&&setw(3)&&10&&setw(3)&&100;输出结果为1 10100(默认是右对齐)当输出长度大于3时(&&1000),setw(3)不起作用。setfill(c)设填充字符为csetioflags(ios::fixed)固定的浮点显示setioflags(ios::scientific)指数表示&&sample cout&&setiosflags(ios::fixed)&&setprecision(2)&&2.345&& output 2.34setiosflags(ios::left)左对齐setiosflags(ios::right)右对齐setiosflags(ios::skipws)忽略前导空白setiosflags(ios::uppercase) 16进制数大写输出setiosflags(ios::lowercase) 16进制小写输出setiosflags(ios::showpoint)强制显示小数点setiosflags(ios::showpos)强制显示符号sample: cout&&setiosflags(ios::uppercase)&&hex&&12&&15&& output&CFcout&&setioflags(ios::showpoint)&&x&&若float x=1,则output 1.000000不使用直接输出1cout&&setiosflags(ios::showpos)&&1&&output +1---------------------------------------------------------------------------------------------------------------------------bits指定的格式标志位,返回旧的格式标志。long fill(char c)&设置填充字符,缺省条件下是空格。char fill( )&返回当前填充字符。int precision(int val)&设置精确度为val,控制输出浮点数的有效位,返回旧值。int precision( )返回旧的精确度值。int width(int val)&设置显示数据的宽度(域宽),返回旧的域宽。int width( )&只返回当前域宽,缺省宽度为0。这时插入操作能按表示数据的最小宽度显示数据。&&预定义的操纵算子&&&使用成员函数控制格式化输入输出时,每个函数调用需要写一条语句,尤其是它不能用在插入或提取运算符的表达式中,而使用操纵算子,则可以在插入和提取运算符的表达式中控制格式化输入和输出。在程序中使用操纵算字必须嵌入头文件iomanip.hdec十进制的输入输出hex十六进制的输入输出oct&八进制的输入输出ws&提取空白字符ends&输出一个nul字符endl&输出一个换行字符,同时刷新流flush刷新流resetiosflags(long)请除特定的格式标志位setiosflags(long)设置特定的格式标志位setfill(char)设置填充字符setprecision(int)设置输出浮点数的精确度setw(int)设置域宽格式变量setiosflags(long)常用的有:ios_base::fixed固定的浮点显示ios_base::scientific指数表示ios_base::left左对齐ios_base:right右对齐ios_base::skipws忽略前导空白ios_base::showpos //正数前加+ios_base::showpoint //总是显示小数点ios_base::uppercase //十六进制大写A..F,浮点数大写Eios_base::showbase //八进制前加0,十六进制前加0x其它流函数错误处理在对一个流对象进行I/O操作时,可能会产生错误。当错误发生时,错误的性质被记录在ios类的一个数据成员中。ios类中定义的描述错误状态的常量:goodbit&没有错误,正常状态eofbit到达流的结尾failbit I/O操作失败,清除状态字后,可以对流继续进行操作。badbit试图进行非法操作,清除状态字后,流可能还可以使用。hardfail致命错误,不可恢复的错误。ostream类的成员函数流的其它成员函数可以从流中读取字符或字符串,对流进行无格式化的输入输出操作,以及直接控制对流的I/O操作。返回类型ios类的成员描可以应用c++的控制文件位置来格式化文件输出,在C语言中,有等效的fseek()函数,可以控制文件指针位置。和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个字节下面是我第一次的程序有关写文件的操作:string area,ofstream outfile(&output.txt&);outfile&&area&&& &&&address&&& &&&num&&下面是改进后的操作:string area,ofstream outfile(&output.txt&);outfile&&outfile.seekp(-strlen(area.c_str()) + 30,ios::cur);outfile&&outfile.seekp(-strlen(address.c_str()) + 30,ios::cur);outfile&&num&&这里用strlen()函数就完美的解决了字符串长度参差不齐的问题。。。。可以通过调用seekp()成员函数来指定逻辑指针到文件中的任一位置,seekp()成员函数通过指定的位置偏移量实现文件中重新定位。在下面的范例中,程序定位到第10字节的文件位置,然后调用tellp()来输出新的位置:ofstream fout(&parts.txt&);fout.seekp(10); // move 10 bytes ahead from beginningcout&&&new position: &&&fout.tellp(); // display 10我在应用tellp成员函数读取文件指针时是这样用的:ifstream infile(&input.txt&)ofstream outfile(&output.txt&)......int temp=infile.tellp();.......infile.seekp(temp);编译器会报错,提示tellp并不是std::ifstream的成员函数,把infile的定义类型改成fstream就行了,也就是:infile.open(&input.txt&); 述ostream* tie(ostream*)&将当前流与指定的输出流连接起来。每当需要读取当前流时,连接的流会自动刷新。C++流库已用cin.tie(cout)将输入流与输出流连接起来。要取消与输出流的连接可采用is.tie(0)&ostream* tie( )返回指向连接流的指针返回类型ostream类的成员描 述ostream& put(char ch)向流中输出一个字符ch,不进行任何转换ostream& write(char*,int)向流中输出指定长度的字符串,不进行转换ostream&&flush( )刷新流,输出所有缓冲的但还未输出的数据ostream& seekp(streampos)移动流的当前指针到给定的绝对位置ostream& seekp(sereamoff,seek_dir)流的当前指针类似与文件的当前指针streampos teelp( )返回流的当前指针的绝对位置istream类的成员函数返回类型istream类的成员描 述int get( )读取并返回一个字符istream& get(char&c)读取字符并存入c中istream& get(char*ptr,int len,char delim='')读取指定的字符到缓冲区中,直到遇到指定的分界符为止,分界符不填入缓冲区。istream& getline(char*ptr,int len,char delim='')与get(char*ptr,int len,chardelim ='')类似,但将分界符填入缓冲区。istream& putback( )将最近读取的字符放回流中istream& read(char*,int)读取规定长度的字符串到缓冲区中函数gcount()返回读取的字节数int peek( )&&返回流中下一个字符,但不移动文件指针istream& seekg(streampos)移动当前指针到一绝对地址istream&&seekg(streampos,seek_dir)移动当前指针到一相对地址streampos tellg( )返回当前指针istream& ignore(int n=1,delim=EOF)跳过流中几个字符,或直到遇到指定的分界符为止getch()函数用于从键盘输入一个字符,不回显,包含头文件&conio.h&中

我要回帖

更多关于 ifstream 按行读取 的文章

 

随机推荐