C++ 使用ifstream.getline()

1、C++ 通过以下几个类支持文件的输入输出:

ofstream: 写操作(输出)的文件类 (由ostream引申而来)
ifstream: 读操作(输入)的文件类(由istream引申而来)
fstream: 可同时读写操作的文件类 (由iostream引申而来)
所有的I/O都以这个“流”类为基础的。

2、下文对ifstream.getline()的用法进行了总结1

2.1三种读取方法:

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;
}
2.2 c++的流析取器 >>

c++的流析取器 >> 从流对象析取内容到右操作数。它的默认分隔符(用以判断某次析取内容边界的字符)是:\t,space,enter.。2

2.3 fstream.getline的参数说明

两个说明,一是fstream.getline的第二个参数需要传入字符数,而非字节数,文档中没有明确说明,俺在这里栽过。二是,如果单行超过了缓冲,则循环会结束。
总结:用getline的时候,一定要保证缓冲区够大,能够容纳各种可能的数据行。切记传入字符数。3

2.4 c_str()使用说明4

语法: 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类型,存放的即为用户输入的文件名。

参考资料


  1. C++ 使用ifstream和getline读取文件内容 ↩︎

  2. 关于c++流析取器>>的分隔符 ↩︎

  3. hfstream.getline的坑 ↩︎

  4. C++中的c_str()函数用法 ↩︎

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐