C++中的文件输入/输出(6):一些有用的函数
原作:Ilia Yordanov,
loobian@cpp-home.com
tellg() ——
返回一个
int
型数值,它表示“内置指针”的当前位置。此函数仅当你在读取一个文件时有效。例如:
#include <fstream.h>
void main()
{
//
假如我们已经在
test_file.txt
中存有了“
Hello
”的内容
ifstream File("test_file.txt");
char arr[10];
File.read(arr,10);
//
由于
Hello
占
5
个字符,因此这里将返回
5
cout << File.tellg() << endl;
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 <fstream.h>
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 << arr << endl;
//
它将显示
"lo World!"
File.close();
}
getline() ——
虽然前面的章节中我曾提到过这个函数,但还有一些内容我们未曾涉及:此函数不但可用于逐行读取,而且它还可以设为遇到某个特定字符后停止读取。下面给出传递这一参数的方法:
getline(array,array_size,delim);
以下为示例代码:
#include <fstream.h>
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 << arr << endl;
//
将显示
"Hell"
File.close();
}
peek() ——
此函数将返回输入流文件的下一个字符,但它不移动内置指针。我想你该记得,像
get()
这样的函数也返回输入流文件的下一个字符,而与此同时它将移动内置指针。所以当你再次调用
get()
函数的时候,它会返回再下一个字符,而非前面那个。哦,使用
peek()
也会返回字符,但它不会移动“光标”。所以,假如你连续两次调用
peek()
函数,它会返回同一个字符。考虑以下代码:
#include <fstream.h>
void main()
{
//
假设
test_file.txt
中已经存有
"Hello World"
这一内容
ifstream File("test_file.txt");
char ch;
File.get(ch);
cout << ch << endl;
//
将显示
"H"
cout << char(File.peek()) << endl;
//
将显示
"e"
cout << char(File.peek()) << endl;
//
将再次显示
"e"
File.get(ch);
cout << ch << endl;
//
还是显示
"e"
File.close();
}
顺便说一下,我忘了讲
——peek()
函数实质上返回的是字符的
ASCII
码,而非字符本身。因此,假如你想看到字符本身,你得像我在示例中做的那样进行调用(译注:即要转为
char
类型)
。
_unlink() ——
删除一个文件。假如你要使用此函数,需要在你的程序中包含
io.h
头文件。下面是示例代码:
#include <fstream.h>
#include <io.h>
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 << "Error...!\n";
//
耶,成功了
File.close();
}
putback() ——
此函数将返回最后一个所读取字符,同时将内置指针移动
-1
个字符。换言之,如果你使用
get()
来读取一个字符后再使用
putback()
,它将为你返回同一个字符,然而同时会将内置指针移动
-1
个字符,所以你再次使用
get()
时,它还是会为你返回同样的字符。下面是示例代码:
#include <fstream.h>
void main()
{
//
test_file.txt
应包含内容
"Hello World"
ifstream File("test_file.txt");
char ch;
File.get(ch);
cout << ch << endl;
//
将显示
"H"
File.putback(ch);
cout << ch << endl;
//
仍将显示
"H"
File.get(ch);
cout << ch << endl;
//
再一次显示
"H"
File.close();
}
flush()
——
在处理输出流文件的时候,你所存入的数据实际上并非立刻写入文件,而是先放入一个缓冲区中,直到该缓冲区放满数据之后,这些数据才被存入真正的文件中(在你的磁盘上)。旋即缓冲区会被清空,再重新进行下一轮写入。
但假如你想在缓冲区写满之前就将其中的数据写入磁盘,则使用
flush()
函数。只须像这样进行调用:
FileHandle.flush()
,这样缓冲区内的数据将会写入实际的物理文件,而后缓冲区被清空。
再补充一点(高阶的)内容:
flush()
函数会调用与相应流缓冲(
streambuf
)相联系的
sync()
函数(出自
MSDN
)。