使用 fstream 的"访问冲突"

'Access violation' using fstream

本文关键字:访问冲突 fstream 使用      更新时间:2023-10-16
#include <iostream>
#include <fstream>
#include <conio.h>
using namespace std;
int main()
{
char r;
fstream file1("text.txt", ios::in |ios::binary);
fstream file2("text.txt", ios::out | ios::binary);
r='r';
for(int i=0; i<100; i++)
    file2.write((char*)r, sizeof(char));
while(!file1.eof()) 
{
    file1.read((char*)r, sizeof(char));
    cout<<r<<"n";
}
file1.close();
file2.close();
getch();
}

当我在vc++ 2010中运行时,我在运行时得到以下错误:

Unhandled exception at 0x55361f68 (msvcp100d.dll) in file io.exe: 0xC0000005: Access       violation reading location 0x00000072.

是什么导致了这个错误?这在读取

这一行时发生:

file2.write ((char *) r, sizeof (char));

我犯了什么错误吗?如果有,请为我指出来(提前感谢)。

Update:我仍然没有得到我预期的输出(在将(char*)r更正为(char*)&r之后)。我得到的输出只是:r.难道我不应该期望从'r'开始显示100个字符吗?如果没有,请告诉我原因并提前表示感谢。

你需要

 file1.read((char*)&r, sizeof(char));

 file1.read(&r, sizeof(char));

除了上述答案,您的代码还存在另一个问题。

流默认执行缓冲I/O;当写入file1时,您所写入的内容可能还没有输出到实际的文件中。为了提高效率,内容实际上存储在一个临时缓冲区中。当close()被调用时,或者当文件流超出作用域并被销毁时,写入实际文件是为显式flush()保留的操作。

代码中的问题是,在直接写入文件流之后,您执行输入而不确定是否将输出数据写入实际文件。如果您假设数据已成功地从输入文件读取到变量,则可能导致未定义行为。

相互依赖的文件流应该同步。也就是说,当文件流试图从您写入的同一文件中读取时,必须刷新输出文件流。这可以通过将流"绑定"在一起来实现,这是使用tie():

完成的。
file1.tie(&file2);

file1执行输入时,file2将被刷新,迫使其缓冲区中的数据写入文件。

另一个问题是你没有检查文件流是否被正确构造,或者你是否已经成功地从file1读取。您可以使用if()语句来执行此操作:

std::fstream file1("text.txt", std::ios_base::in  | std::ios_base::binary);
std::fstream file2("text.txt", std::ios_base::out | std::ios_base::binary);
char r('r');
if (file1 && file2)
{
    file1.tie(&file2);
    for (int i = 0; i < 100; ++i)
        file2.write(&r, sizeof(char));
    while (file1.read(&r, sizeof(char))) {
        std::cout << r << std::endl;
    }
}

在写入文件后立即开始从该文件读取,并且没有关闭写入文件流。在关闭写文件流之前,它不会提交写操作。因此,当它保持控制时,会发生访问冲突的变化。

试试下面的代码

#include <iostream>
#include <fstream>
#include <conio.h>
using namespace std;
int main()
{
char *r="r";
fstream file2("text.txt", ios::out | ios::binary);
for(int i=0; i<100; i++)
    file2.write((char*)r, sizeof(char));
file2.close();
fstream file1("text.txt", ios::in |ios::binary);
while(!file1.eof()) 
{
    char rr;
    file1.read(&rr, sizeof(char));
    cout<<rr<<"n";
}
file1.close();
getch();
}

您尝试将单个字符强制转换为char *,并且还尝试在不传递r地址的情况下使用fread进行读取。这就是问题出现的原因。请仔细看我上面的代码,它会解决你的问题。