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

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

你好,我得到了一个作业,要使用运算符[]通过 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");
}

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

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

文件class是这样定义的:

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

通常的方法是定义一个helperclass:

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;
   }
};

你的 [] 运算符然后 returns 这个助手 class,而不是普通的 char.

assignment_helper operator[](size_t index);

因此,当它用于赋值操作时:

file[10]='x';

operator[] returns 这个助手的一个实例 class, = 调用它的赋值运算符,将要赋值的字符作为参数,并且operator= 将此参数转发给 File 中的 put() 方法,该方法会执行任何需要执行的操作以更新文件的内容。

索引位置和指向 File 对象的指针保存在助手 class 中,以实现此目的。此外,如果您仍想访问文件的现有内容,例如:

char c=file[10];

赋值运算符也实现了char运算符。 [] 运算符也传递该位置的现有字符,该字符保存在助手 class 中,并由 char 运算符返回。

你遇到的问题是你需要 operator[] 到 return 一个引用,然后你可以将你的角色分配给它,这将操纵文件:

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

由于您不能 return 对文件中保存的字符的引用,因此您需要 return 对 class 的引用('something' ) 可以在您调用其 operator=(char) 时为您执行操作。作为奖励,您还可以包含一个 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;
}