C ++如何使用带有[]运算符的fstream更改文件的字符

c++ how can i change a char of a file using fstream with [] operator

本文关键字:fstream 字符 文件 运算符 何使用      更新时间:2023-10-16

您好,我接到了一个使用运算符 [] 使用 fstream 更改 txt 文件中的字符的任务。
为了获得字符,我使用了这个:

char File::operator[](int index)
{
char c;
for (int i = 0; i <= index; ++i)
{
ifs.get(c);
}
return c;
}

现在我做了一个函数,在没有 [] 的情况下替换文件中的字符:

void Change(ifstream& ifs, int index, char ch)
{
ofstream ofs("D:\temp.txt");
char c;
while (ifs.get(c))
{
ofs.put(c);
}
ofs = ofstream("D:\test.txt", ios_base::trunc);
ifs = ifstream("D:\temp.txt");
for (int i = 0; i < index; i++)
{
ifs.get(c);
ofs.put(c);
}
ifs.get(c);
ofs.put(ch);
while (ifs.get(c))
{
ofs.put(c);
}
remove("D:\temp.txt");
}

如果您有想法,请发布 我想不出解决这个问题的方法。 现在有一个提示,那就是你需要使用一个对象来改变。 所以基本上我不明白如何允许:

File f("D:\test.txt");
f[0] = 'y';

文件类是这样定义的:

class File
{
public:
File(string loc) :loc(loc), ifs(loc, ios_base::in) {}
char operator[](int index);
~File();
private:
string loc;
ifstream ifs;
};

通常的方法是定义一个帮助程序类:

class assignment_helper {
char v;
size_t i;
File *p;
public:
assignment_helper(char v_, size_t i_, File *p_) : v(v_), p(p_), i(i_) {}
operator char() const { return v; }
assignment_helper &operator=(char new_char)
{
p->Change(i, new_char);
return *this;
}
};

然后,您的[]运算符将返回此帮助程序类,而不是普通char

assignment_helper operator[](size_t index);

因此,当在赋值操作中使用此功能时:

file[10]='x';

operator[]返回此帮助器类的实例,=调用其赋值运算符,将字符作为参数赋值,operator=将此参数转发给File中的put()方法,该方法执行更新文件内容所需的任何操作。

索引位置和指向File对象的指针保存在帮助程序类中,以便实现此目的。此外,如果您仍希望访问文件的现有内容,例如:

char c=file[10];

赋值运算符还实现char运算符。[]运算符也会传递该位置的现有字符,该字符保存在帮助程序类中,并由char运算符返回。

您遇到的问题是您需要operator[]返回一个引用,然后您可以将您的字符分配给该引用,这将操作文件:

'something'& operator[](int index);

由于您无法返回对文件中保存的字符的引用,因此您需要返回对一个类("something")的引用,该类可以在您调用其operator=(char)时为您执行操作。作为奖励,您还可以包含一个字符转换运算符来读取字符(operator char())。

下面是代码形式的解释:

class FileCharProxy
{
public:
FileCharProxy(std::iostream& stream, int index) : stream(stream), index(index) { }
operator char() const
{
stream.seekg(index);
char ch = stream.get();
return ch;
}
FileCharProxy& operator=(char ch)
{
stream.seekp(index);
stream.put(ch);
return *this;
}
private:
std::iostream& stream;
int index;
};
class File
{
public:
File(std::string loc) :loc(loc), fs(loc) {}
FileCharProxy operator[](int index)
{
return FileCharProxy { fs, index };
}
private:
std::string loc;
std::fstream fs;
};

你可以这样称呼它:

std::ostream& operator << (std::ostream &s, FileCharProxy &p)
{
s << static_cast<char>(p);
return s;
}
int main(int argc, char*argv[])
{
File myfile("modify_file.data");
auto ch = myfile[2];
std::cout << "Character was: " << ch << std::endl;
std::cout << "Character will be: " << static_cast<char>(ch + 1) << std::endl;
myfile[2] = myfile[2] + 1;
}