c++ 文本文件读写

我在.txt文件中有int id;string name;int date;等元素,这些东西都写在一行里,我想把它们读出来,不知道怎么读,我只会一行一行的读

大多数 C++ 程式员都熟悉不止一个文件 I/O 库。首先是传统的 Unix 风格的库,他由一些低级函数如 read() 和
open()组成。其次是 ANSI C 的 库,他包含 fopen() 和
fread()等函数。其他的更有一些具有所有权的库或框架,比如 MFC,他有非常多自己的文件处理类。
这些库一般都非常难跨平台使用。更糟的是,上述提到的 C 库由于其程式接口的原因,在非常大程度上强制程式员进行某些处理,而且缺乏类型安全支持。

标准 C++ 提供提供了一个增强的、面向对象的、具有国际化意识的 库。这个库包含一系列派生于标准
ios_base 和 ios 类的类模板。因此, 提供了高级的自动控制机制和健壮性。本文下面将示范怎么使用
类实现文件的输入/输出处理:
1。打开文件
void open(const char *_Filename, ios_base::open_mode _Mode)
void open(const char *_Filename, ios_base::openmode _Mode = ios_base::out, int _Prot = (int)ios_base::_Openprot)
打开模式:
ios::app // 从后面添加
ios::ate // 打开并找到文件尾
ios::binary // 二进制模式 I/O (和文本模式相对)
ios::in // 只读打开
ios::out // 写打开
ios::trunc // 将文件截为 0 长度
保护方式:
filebuf::openprot // 兼容共享方式
filebuf::sh_none // 独占,不共享
filebuf::sh_read
filebuf::sh_write
2。检测是否打开:
ofstream File1;
cout
2.。检测打开成功和否:
ofstream File("unexisting.txt", ios::nocreate);

if(!File)
{
cout
exit(1);
}
==============================================
ofstream File("filer.txt", ios::nocreate);

if(File.fail())
{
cout
exit(1);
}
3:设置文件的位置
ofstream fout("parts.txt");fout.seekp(10); // 从0偏移开始前进 10 个字节cout
你能用下面的常量重新定位文ian指针:
ios::beg // 文件开始位置ios::cur // 当前位置,例如: ios::cur+5ios::end // 文件尾
File.seekg(-5);
File.seekg(40);
File.seekg(-5,ios::end);//读到文件文本的最后4个字符
4.

检测输入/输出的状态标志
C++中负责的输入/输出的系统包括了关于每一个输入/输出操作的结果的记录信息。这些当前的状态信息被包含在io_state类型的对象中。io_state是个枚举类型(就像open_mode相同),以下便是他包含的值(译注:表中第一列为枚举值的名称,第二列为该值相应含义的描述):

godbit
无错误
Eofbit
已到达文件尾
failbit
非致命的输入/输出错误
badbit
致使的输入/输出错误

有两种方法能获得输入/输出的状态信息。一种方法是通过调用rdstate()函数,他将返回当前状态的错误标记(上表中提到的)。例如,如果没有所有错误,则rdstate()会返回goodbit.
另一种方法则是使用下面所有一个函数来检测相应的输入/输出状态:

bool bad();
bool eof(); //还记得他么?“不断读取文件内容直到到达文件末尾!”
bool fail(); //噢,这也是老朋友……检测一个打开操作是否成功
bool good();

如果badbit标志被标设(译注:原文为“If the badbit flag is up”,这里将“is up”译为“标设”,意即出现了badbit对应的错误,badbit状态被置为当前的错误状态,下同),则bad()函数返回true;如果failbit标志被标设,则fail()函数返回true;如果没有错误发生(goodbit标志被标设),则good()函数返回true;如果操作已到达了文件末尾(eofbit被标设),则eof()函数返回true.
如果错误发生,你必须清除这些错误状态,以使你的程式能正确适当地继续运行??如果你这么打算的话。要清除错误状态,需使用clear()函数。此函数带一个参数,他是你将要设为当前状态的标志值。假使你想让你的程式“清清爽爽”地运行下去,只要将ios::goodbit作为实参。你将在以下内容中看到示例代码。
我将向你展示示例代码,以巩固你所学到的理论知识。

示例1:简单的状态检测

// 实际应用中可将 FileStream替换成你相应在使用的文件流句柄
if(FileStream.rdstate() == ios::eofbit)
cout
if(FileStream.rdstate() == ios::badbit)
cout
if(FileStream.rdstate() == ios::failbit)
cout
if(FileStream.rdstate() == ios::goodbit)
cout

示例2:clear()函数

#include

void main()
{
ofstream File1("file2.txt"); //建立file2.txt
File1.close();

// 下面的检测代码将会返回错误,这是因为我使用了ios::noreplace打开模式
// 他模式在试图打开一个已存在的文件时会返回错误
ofstream Test("file2.txt",ios::noreplace);

// 上一行将导致ios::failbit错误,我们这就将其演示出来
if(Test.rdstate() == ios::failbit)
cout

Test.clear(ios::goodbit); // 将当前状态重置为ios::goodbit

if(Test.rdstate() == ios::goodbit) // 检测程式是否已正确地施行了设置
cout

Test.clear(ios::eofbit); // 将状态标志设为ios::eofbit. 无实际用途.

if(Test.rdstate() == ios::eofbit) // 检测是否已正确地施行了设置 cout

Test.close();

}

除了使用标记值判断,你也能使用函数(译注:指bad()、eof()、fail()、good()这些函数)的形式进行判断,两者实际上是相同的??都是检测某个标记是否被标设。这些函数前面已介绍过,我就不再重复了。如果你对怎么使用他们还不是十分确定,那就重新回顾一下本教程中我原来为你演示的应该怎么检测一个文件打开操作是否成功的那部分内容。在那里我就使用了fail()函数。
5.二进制文件的处理
虽然有规则格式(formatted)的文本(到目前为止我所讨论的所有文件形式)非常有用,但有时候你需要用到无格式(unformatted)的文件??二进制文件。他们和你的可执行程式看起来相同,而和使用及>>操作符创建的文件则大不相同。
首先设置ios::binary
然后使用函数:
读取一个字节:get() put()
读/写一整块的数据:
istream &read(char *buf, streamsize num);
ostream &write(const char *buf, streamsize num);
示例1:使用get( )和put( )

#include

void main()
{
fstream File("test_file.txt",ios::out | ios::in | ios::binary);

char ch;
ch=’o’;

File.put(ch); // 将ch的内容写入文件

File.seekg(ios::beg); // 定位至文件首部

File.get(ch); // 读出一个字符

cout // 将其显示在屏幕上

File.close();
}

示例2:使用read( )和write( )

#include
#include

void main()
{
fstream File("test_file.txt",ios::out | ios::in | ios::binary);

char arr[13];
strcpy(arr,"Hello World!"); //将Hello World!存入数组

File.write(arr,5); // 将前5个字符??"Hello"写入文件

File.seekg(ios::beg); // 定位至文件首部

static char read_array[10]; // 在此我将打算读出些数据

File.read(read_array,3); // 读出前三个字符??"Hel"

cout // 将他们输出

File.close();
}
6.常用函数:
tellg() ??返回一个int型数值,他表示“内置指针”的当前位置。此函数仅当你在读取一个文件时有效。例如:
#include

void main()
{
// 如果我们已在test_file.txt中存有了“Hello”的内容
ifstream File("test_file.txt");

char arr[10];

File.read(arr,10);

// 由于Hello占5个字符,因此这里将返回5
cout
File.close();
}

tellp() ?? 和tellg()有同样的功能,但他用于写文件时。总而言之:当我们读取一个文件,并要知道内置指针的当前位置时,应该使用tellg();当我们写入一个文件,并要知道内置指针的当前位置时,应该使用tellp(). 由于此函数的用法和tellg()完全相同,我就不给出示例代码了。

seekp() ?? 还记得seekg()么?当我在读取一个文件,并想到达文件中某个特定位置时,就曾使用过他。seekp()亦如此,只不过他用于写入一个文件的时候。例如,如果我在进行文件读写,而要定位到当前位置的三个字符之前,则需调用FileHandle.seekg(-3). 但如果我是在写入一个文件,并且比如我要重写后5个字符的内容,我就必须往回跳转5个字符,因而,我应该使用FileHandle.seekp(-5) .

ignore() ?? 使用于读取文件之时。如果你想略过一定数量的字符,只需使用此函数。实际上,你也能使用seekg()来代替,然而使用ignore()有一个好处??你能指定一个特定“界限规则(delimiter rule)”,同样使得ignore()在指定的位置停下。函数原型如下:

istream& ignore( int nCount, delimiter );

nCount表示要略过的字符数量,而delimiter ?? 和他的名称有着同样的含义:如果你想在文件末尾停下,则可使用EOF值传入,这样一来此函数就等同于seekg();但该参数还能使用其他值,例如‘\n’这样能在换行的同时定位在新行处。下面是示例:
#include

void main()
{
// 假设test_file.txt中已存有"Hello World"这一内容
ifstream File("test_file.txt");

static char arr[10];

// 如果一直没有遇见字符"l",则向前定位直到跳过6个字符
// 而如果期间遇见"l",则停止向前,定位在该处
File.ignore(6,’l’);

File.read(arr,10);

cout // 他将显示"lo World!"

File.close();

}

getline() ?? 虽然前面的章节中我曾提到过这个函数,但更有一些内容我们未曾涉及:此函数不仅可用于逐行读取,而且他还能设为遇见某个特定字符后停止读取。下面给出传递这一参数的方法:

getline(array,array_size,delim);

以下为示例代码:

#include

void main()
{
// 假设test_file.txt中已存有"Hello World"这一内容
ifstream File("test_file.txt");

static char arr[10];

/* 读取,直到满足下面的条件之一:
1)已读取10个字符
2)遇见字母"o"
3)出现新一行
*/
File.getline(arr,10,’o’);

cout // 将显示"Hell"
File.close();
}

peek() ?? 此函数将返回输入流文件的下一个字符,但他不移动内置指针。我想你该记得,像get()这样的函数也返回输入流文件的下一个字符,而和此同时他将移动内置指针。所以当你再次调用get()函数的时候,他会返回再下一个字符,而非前面那个。哦,使用peek()也会返回字符,但他不会移动“光标”。所以,如果你连续两次调用peek()函数,他会返回同一个字符。考虑以下代码:

#include

void main()
{
// 假设test_file.txt中已存有"Hello World"这一内容
ifstream File("test_file.txt");

char ch;

File.get(ch);
cout // 将显示"H"

cout char(File.peek()) //将显示"e"
cout char(File.peek()) //将再次显示"e"

File.get(ch);
cout // 还是显示"e"

File.close();

}

顺便说一下,我忘了讲??peek()函数实质上返回的是字符的ASCII码,而非字符本身。因此,如果你想看到字符本身,你得像我在示例中做的那样进行调用(译注:即要转为char类型)。

_unlink() ?? 删除一个文件。如果你要使用此函数,需要在你的程式中包含io.h头文件。下面是示例代码:

#include
#include

void main()
{
ofstream File;

File.open("delete_test.txt"); //创建一个文件
File.close();

_unlink("delete_test.txt"); // 删除这个文件

// 试图打开此文件,但如果他已不存在
// 函数将返回一个ios::failbit错误值
File.open("delete_test.txt",ios::nocreate);

// 验证他是否返回该值
if(File.rdstate() == ios::failbit)
cout // 耶,成功了

File.close();

}

putback() ?? 此函数将返回最后一个所读取字符,同时将内置指针移动-1个字符。换言之,如果你使用get()来读取一个字符后再使用putback(),他将为你返回同一个字符,然而同时会将内置指针移动-1个字符,所以你再次使用get()时,他还是会为你返回同样的字符。下面是示例代码:

#include

void main()
{
// test_file.txt应包含内容"Hello World"
ifstream File("test_file.txt");

char ch;

File.get(ch);

cout // 将显示"H"

File.putback(ch);
cout // 仍将显示"H"

File.get(ch);
cout // 再一次显示"H"

File.close();
}

flush() ?? 在处理输出流文件的时候,你所存入的数据实际上并非即时写入文件,而是先放入一个缓冲区中,直到该缓冲区放满数据之后,这些数据才被存入真正的文件中(在你的磁盘上)。旋即缓冲区会被清空,再重新进行下一轮写入。
但如果你想在缓冲区写满之前就将其中的数据写入磁盘,则使用flush()函数。只须像这样进行调用:FileHandle.flush(),这样缓冲区内的数据将会写入实际的物理文件,而后缓冲区被清空。
再补充一点(高阶的)内容:flush()函数会调用和相应流缓冲(streambuf)相联系的sync()函数
温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-04-02
那你就读一行字符串出来,然后再对读出来的字符串进行分析处理。
第2个回答  2010-04-02
ifstream fin(".txt");
while(fin >> id >> name >> date);本回答被提问者采纳
相似回答