ofstream: 写操作(输出)的文件类 (由ostream引申而来) ifstream: 读操作(输入)的文件类(由istream引申而来) fstream: 可同时读写操作的文件类 (由iostream引申而来) 所有的I/O都以这个“流”类为基础的。
1)读取方式: 逐词读取, 词之间用空格区分:void ReadDataFromFileWBW()。 2)读取方式: 逐行读取, 将行读入字符数组, 行之间用回车换行区分:ReadDataFromFileLBLIntoCharArray()。 3)读取方式: 逐行读取, 将行读入字符串, 行之间用回车换行区分:ReadDataFromFileLBLIntoString()。
#include <iostream> #include <fstream> #include <string> using namespace std; //输出空行 void OutPutAnEmptyLine() { cout<<"\n"; } //读取方式: 逐词读取, 词之间用空格区分 //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"); string s; // c++的流析取器 >> 从流对象析取内容到右操作数。 //它的默认分隔符(用以判断某次析取内容边界的字符)是:\t,space,enter. while( fin >> s ) { cout << "Read from file: " << s << endl; } } //读取方式: 逐行读取, 将行读入字符数组, 行之间用回车换行区分 //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"); const int LINE_LENGTH = 100; //一:fstream.getline的第二个参数需要传入字符数,而非字节数,文档中没有明确说明。 //二:如果单行超过了缓冲,则循环会结束。 //总结:用getline的时候,一定要保证缓冲区够大,能够容纳各种可能的数据行。切记传入字符数。 //在此例中则为创建"data.txt"的时候,每一行的字符数不要超过100,否则while循环会结束。 char str[LINE_LENGTH]; while( fin.getline(str,LINE_LENGTH) ) { cout << "Read from file: " << str << endl; } } //读取方式: 逐行读取, 将行读入字符串, 行之间用回车换行区分 //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"); string s; while( getline(fin,s) ) { cout << "Read from file: " << s << endl; } } //带错误检测的读取方式 //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()); //c_str()函数返回一个指向正规C字符串的指针常量, 内容与本string串相同. //这是为了与c语言兼容,在c语言中没有string类型, //故必须通过string类对象的成员函数c_str()把string 对象转换成c中的字符串样式。 //实际上此处没必要使用c_str(),直接使用fin(filename) 或fin("dataFUNNY.txt")都可 if( !fin ) { cout << "Error opening " << filename << " for input" << endl; system("pause"); exit(-1); } } int main() { ReadDataFromFileWBW(); //逐词读入字符串 OutPutAnEmptyLine(); //输出空行 ReadDataFromFileLBLIntoCharArray(); //逐词读入字符数组 OutPutAnEmptyLine(); //输出空行 ReadDataFromFileLBLIntoString(); //逐词读入字符串 OutPutAnEmptyLine(); //输出空行 ReadDataWithErrChecking(); //带检测的读取 return 0; }c++的流析取器 >> 从流对象析取内容到右操作数。它的默认分隔符(用以判断某次析取内容边界的字符)是:\t,space,enter.。2
两个说明,一是fstream.getline的第二个参数需要传入字符数,而非字节数,文档中没有明确说明,俺在这里栽过。二是,如果单行超过了缓冲,则循环会结束。 总结:用getline的时候,一定要保证缓冲区够大,能够容纳各种可能的数据行。切记传入字符数。3
语法: const char *c_str();
c_str()函数返回一个指向正规C字符串的指针常量, 内容与本string串相同. 这是为了与c语言兼容,在c语言中没有string类型,故必须通过string类对象的成员函数c_str()把string 对象转换成c中的字符串样式。 注意:一定要使用strcpy()函数 等来操作方法c_str()返回的指针 比如:最好不要这样: char* c; string s=“1234”; c = s.c_str(); //c最后指向的内容是垃圾,因为s对象被析构,其内容被处理,同时,编译器也将报错——将一个const char *赋与一个char *。
应该这样用: char c[20]; string s=“1234”; strcpy(c,s.c_str()); 这样才不会出错,c_str()返回的是一个临时指针,不能对其进行操作 c_str()返回的是一个分配给const char的地址,其内容已设定为不可变更,如果再把此地址赋给一个可以变更内容的char变量,就会产生冲突,在2010中是不被允许的。但是如果放入函数调用,或者直接输出,因为这些函数和输出都是把字符串指针作为 const char*引用的,所以不会有问题。
再举个例子 c_str() 以 char* 形式传回 string 内含字符串 如果一个函数要求char*参数,可以使用c_str()方法: string s = “Hello World!”; printf("%s", s.c_str()); //输出 “Hello World!”
当需要打开一个由用户自己输入文件名的文件时,可以这样写:ifstream in(st.c_str());。其中st是string类型,存放的即为用户输入的文件名。
C++ 使用ifstream和getline读取文件内容 ↩︎
关于c++流析取器>>的分隔符 ↩︎
hfstream.getline的坑 ↩︎
C++中的c_str()函数用法 ↩︎