zl程序教程

您现在的位置是:首页 >  后端

当前栏目

【贪玩巴斯】C/C++文件IO流操作的 seekp和seekg详解「建议收藏」

C++文件IO 详解 操作 建议 收藏 seekg
2023-06-13 09:11:56 时间

大家好,又见面了,我是你们的朋友全栈君。

文件流对象有两个成员函数,分别是 seekp 和 seekg。

它们可以用于将读写位置移动到文件中的任何字节。

1.seekp和seekg的区别和记忆点

1.seek 是寻找 寻求的意思 2.tell 是告诉 告知的意思 3.那 p 即put 放和输出的意思,在这里是保存到文件 4.那 g 即get 是获取,读入的意思,在这里是从文件读取

所以

1.seekp 可用于将信息 put(放入 写入)到文件中 2.seekg 则可用于从文件中 get(获取)信息。 3. tellg()函数不需要带参数,它返回当前定位指针的位置,也代表着输入流的大小。

2. seekp 的用法示例:

file.seekp(20L, ios::beg);

第一个实参是一个 long 类型的整数,表示文件中的偏移量。这就是想要移动到的字节数。在该示例中,使用的是 20L(请记住,L 字符可以强制编译器将该数字视为一个 long 类型的整数)。该语句可以将文件的写入位置移动到编号为 20 的字节(所有编号从 0 开始,因此编号为 20 的字节实际上是第 21 个字节)。

第二个实参称为模式标志,它指定从哪里计算偏移量。标志 ios::beg 表示偏移量是从文件开头算起的。也可以修改该参数,从文件末尾或文件中的当前位置计算偏移量。下面列出了所有 3 种随机访问模式的标志。

文件定位标志模式标志 描述 ios::beg 从文件头开始计算偏移量 ios::end 从文件末尾开始计算偏移量 ios::cur 从当前位置开始计算偏移量

beg : 即 begin 开始 end : 即 end 结尾 cur : 即 current 当前

file.seekp(20, ios::beg);

首先 seekp, 最后字母是p , 即写入 (不是读取)

即 该语句可以将文件的写入位置 从 ios::beg (文件开头算起)移动到编号为 20 的字节,所有编号从 0 开始,因此编号为 20 的字节实际上是第 21 个字节)。

3.下面 显示了 seekp 和 seekg 使用不同模式标志的示例。

文件寻找操作

语 句 如何影响读/写位置 file.seekp(32L, ios::beg); 将写入位置设置为从文件开头开始的第 33 个字节(字节 32) file.seekp(-10L, ios::end); 将写入位置设置为从文件末尾开始的第 11 个字节(字节 10) file.seekp(120L, ios::cur); 将写入位置设置为从当前位置开始的第 121 个字节(字节 120) file.seekg(2L, ios::beg); 将读取位置设置为从文件开头开始的第 3 个字节(字节 2) file.seekg(-100L, ios::end); 将读取位置设置为从文件末尾开始的第 101 个字节(字节 100) file.seekg(40L, ios::cur); 将读取位置设置为从当前位置开始的第 41 个字节(字节 40) file.seekg(0L, ios:rend); 将读取位置设置为文件末尾

请注意,上面的一些示例使用了负偏移量。负偏移量导致读或写位置在文件中向后移动,而正偏移量则导致向前移动。

四、下面来分析一个较完整的示例。

假设文件test。txt为以下内容:

hello,my world

name:测试人名

date:20191121

程序为:

Byte 5 from beginning: f
Byte 10 from end: q
Byte 3 from current: u

//This program demonstrates the seekg function.
#include <iostream>
#include <fstream>
usingnamespace std;
int main()
{ 
   
// Variable to access file
char ch;
// Open the file for reading
fstream file ("letters.txt", ios::in);
if (!file)
{ 
   
cout << "Error opening file.";
return 0;
}
// Get fifth byte from beginning of alphabet file
file.seekg(5L, ios::beg);
file.get(ch);
cout << "Byte 5 from beginning: " << ch << endl;
// Get tenth byte from end of alphabet file
file.seekg(-10L, ios::end);
file.get(ch);
cout << "Byte 10 from end: " << ch << endl;
//Go forward three bytes from current position
file.seekg(3L, ios::cur);
file.get(ch);
cout << "Byte 3 from current: " << ch << endl;
// Close file
file.close ();
return 0;
}

则结果输出:

file size:

45

from file to point:

30

hello,my world

name:测试人名

date:20191121

date:20191121

五、下面的程序使用了 seekg 函数跳转到 letters.txt 文件中的不同位置,

每次停止后都检索一个字符:

假设文件 letters.txt 中包含以下数据:

Byte 5 from beginning: f Byte 10 from end: q Byte 3 from current: u

//This program demonstrates the seekg function. #include #include usingnamespace std; int main() { // Variable to access file char ch; // Open the file for reading fstream file (“letters.txt”, ios::in); if (!file) { cout << “Error opening file.”; return 0; } // Get fifth byte from beginning of alphabet file file.seekg(5L, ios::beg); file.get(ch); cout << “Byte 5 from beginning: ” << ch << endl; // Get tenth byte from end of alphabet file file.seekg(-10L, ios::end); file.get(ch); cout << “Byte 10 from end: ” << ch << endl; //Go forward three bytes from current position file.seekg(3L, ios::cur); file.get(ch); cout << “Byte 3 from current: ” << ch << endl; // Close file file.close (); return 0; }

程序输出结果:

Byte 5 from beginning: f Byte 10 from end: q Byte 3 from current: u

下面的程序显示了 seekg 函数的另一个例子。它打开了包含两个记录的 people.dat 文件。该程序首先显示记录 1(第二条记录),然后显示记录 0。

// This program demonstrates the use of a structure // variable to read a record of information from a file. #include #include usingnamespace std; const int NAME_SIZE = 51, ADDR_SIZE = 51, PHONE_SIZE = 14; //声明记录的结构 struct Info { char name[NAME_SIZE]; int age; char address1[ADDR_SIZE]; char address2[ADDR_SIZE]; char phone[PHONE_SIZE]; }; // Function Prototypes long byteNum(int); void showRec(Info); int main() { // Person information Info person; // Create file object and open the file fstream people(“people.dat”, ios::in | ios::binary); if (!people) { cout << “Error opening file. Program aborting.\n”; return 0; } // Skip forward and read record 1 in the file cout << “Here is record 1:\n”; people.seekg(byteNum(1), ios::beg); people.read(reinterpret_cast<char *>(&person), sizeof (person)); showRec(person); // Skip backwards and read record 0 in the file cout << “\nHere is record 0:\n”; people.seekg(byteNum(0), ios::beg); people.read(reinterpret_cast<char *>(&person), sizeof (person)); showRec(person); // Close the file people.close(); return 0; } long byteNum(int recNum) { returnsizeof (Info) * recNum; } void showRec(Info record) { cout << “Name:”; cout << record.name << endl; cout << “Age: “; cout << record.age << endl; cout << “Address line 1: “; cout << record.address1 << endl; cout << “Address line 2: “; cout << record.address2 << endl; cout << “Phone: “; cout << record.phone << endl; }

程序屏幕输出结果:

Here is record 1: Name:cyuyan Age: 20 Address line 1: No.1 Address line 2: No.2 Phone: 12345678

Here is record 0: Name:http://c.biancheng.net Age: 5 Address line 1: No.1 Address line 2: No.2 Phone: 123456

该程序除了 main 以外还有两个重要的函数。第一个是 byteNum,它釆用一个记录编号作为实参,并返回该记录的起始字节。它通过将记录编号乘以 Info 结构的大小来计算记录的起始字节。这将从文件的开始处返回该记录的偏移量。第二个函数是 showRec,它接收一个 Info 结构作为实参,并在屏幕上显示其内容。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/137448.html原文链接:https://javaforall.cn