简体   繁体   English

从文件读取(ifstream)和写入文件(ofstream)-编码问题

[英]Read from file (ifstream) and write to file (ofstream) - problems with encoding

Note: I'm rather a c++ rookie. 注意:我是C ++新手。

I've the following problem: 我有以下问题:

I read from a file and want to replace string parts with other string parts. 我从文件中读取内容,并希望将字符串部分替换为其他字符串部分。 Simple task, should be easy to do. 简单的任务,应该很容易做到。 I did some experiments with setmode, but without success. 我用setmode做了一些实验,但是没有成功。 I googled also imbue, but it didn't help me either. 我还用谷歌搜索,但也没有帮助我。

There might be minor code issues, but please focus on the problem. 可能存在一些小代码问题,但请着重解决该问题。 The test data for conversion is given below: 转换测试数据如下:

int main(int argc, char** argv) {
    stringstream strs;

    //Choose output file
    ofstream ofile;
    string filename;
    cout << "Ausgabepfad eingeben" << endl;
    cin >> filename;
    ofile.open(&filename[0]);

    //Choose input file
    ifstream ifile;
    cout << "Quellpfad eingeben" << endl;
    cin >> filename;
    ifile.open(&filename[0]);

    //Choose decoding - doesnt work, I know - That was for experiments
    int mode = 0;
    cout << "Decoding wählen\n1 für _O_TEXT\n2 für _O_BINARY\n3 für _O_U16TEXT\n4 für _O_U8TEXT\n5 für _O_WTEXT" << endl;
    cin >> mode;
/*    switch(mode){
        case 1:
            _setmode (_fileno(ifstream), _O_TEXT);
        break;
        case 2:
            _setmode (_fileno(ifstream), _O_BINARY);
        break;
        case 3:
            _setmode (_fileno(ifstream), _O_U16TEXT);
        break;
        case 4:
            _setmode (_fileno(ifstream), _O_U8TEXT);
        break;
        case 5:
            _setmode (_fileno(ifstream), _O_WTEXT);
        break;
        default:
            cerr << "ungültige Codierung gewählt"
    }
*/    

    //Choose search string and replacement string
    ifile.seekg(0); //not necessary, I know
    string searchstr = "";
    cout << "Suchstring eingeben" << endl;
    cin >> searchstr;
    string fillstr;
    cout << "Ersetzungsstring eingeben" << endl;
    cin >> fillstr;
    cout << fillstr;
    int marker = 0;
    if(searchstr.length()<1){
        return 0;
    }

    //actual program
    while(!ifile.eof()){
        int counter = 0;
        ifile.seekg(marker);
        char current = ifile.get();
        if(current==searchstr[0]){ //if the first search letter matches, seet, if the others do.
            marker++;
            counter++;
            for(int i = 1; i < searchstr.length(); i++){
                ifile.seekg(marker);
                if(ifile.get()==searchstr[i]){
                    counter++;
                    marker++;
                }else{
                    marker-i;
                    break;
                }
            }
            if(counter == searchstr.length()){
                ofile << fillstr;
                cout << endl;
            }
        }else{
            ofile << ifile.get();
            cout << ifile.get();
        }
        marker++;

    }

    ifile.close();
    ofile.close();
    cout << endl;
    return 1;
}

The following string 以下字符串

|-

should be replaced by 应该替换为

\n

The text (sample) is: 文本(示例)为:

|[[Allgemeines Deutsches Kommersbuch:1|1]] 
|1 
|[[Abend wird's, des Tages (Körner)]] 
|[[Die Eichen (Körner)]]
|-
|[[Allgemeines Deutsches Kommersbuch:2|2]] 
|2 

The program runs, but it doesn't work. 该程序运行,但是不起作用。 The output is lots of numbers without any sense. 输出的数字很多,毫无意义。

The output is lots of numbers without any sense. 输出的数字很多,毫无意义。

The call ifile.get() returns a value of type int_type . 调用ifile.get()返回一个int_type类型的值。 Thus << outputs all these integer values. 因此<<输出所有这些整数值。

Replace 更换

ofile << ifile.get();

(doing formatted output of integers) with (做格式化的整数输出)

ofile << char( ifile.get() );

or (preferred, using unformatted input and output) 或(首选,使用未格式化的输入输出)

ofile.put( ifile.get() );

It's almost always a better idea to express the problem in terms of standard streams, iterators and algorithms: 用标准流,迭代器和算法来表达问题几乎总是一个更好的主意:

#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>

// lets get the logic right in terms of streams


void replace_all(std::ostream& dest, std::istream& source, 
                 const std::string& search_for, const std::string& replace_with)
{
    std::string line;
    while (std::getline(source, line)) {
        auto ipos = line.begin();
        while (ipos != line.end())
        {
            ipos = std::search(ipos, line.end(), search_for.begin(),
                               search_for.end());
            if (ipos != line.end())
            {
                auto start_index = std::distance(line.begin(), ipos);
                line.replace(ipos, std::next(ipos, search_for.length()), 
                             replace_with);
                ipos = std::next(line.begin() + start_index + replace_with.length());
            }
        }
        dest.write(line.data(), line.size());
        dest.put('\n');
    }

}

// now test
int main()
{
    std::string search_for = "|-";
    std::string replace_with = "";

    std::istringstream source_stream("|[[Allgemeines Deutsches Kommersbuch:1|1]]\n"
                                     "|1\n"
                                     "|[[Abend wird's, des Tages (Körner)]]\n"
                                        "|[[Die Eichen (Körner)]]\n"
                                        "|-\n"
                                        "|[[Allgemeines Deutsches Kommersbuch:2|2]]\n"
                                     "|2\n");

    std::ostringstream dest_stream;

    replace_all(dest_stream, source_stream, search_for, replace_with);

    std::cout << dest_stream.str();

    return 0;
}

// todo: write a new main which asks for filenames, builds ifstreams and ofstreams, and calls replace_all()

expected output: 预期输出:

|[[Allgemeines Deutsches Kommersbuch:2|2]]
|2
Jewels-MacBook-Pro:play richardh$ ./replace.cpp
|[[Allgemeines Deutsches Kommersbuch:1|1]]
|1
|[[Abend wird's, des Tages (Körner)]]
|[[Die Eichen (Körner)]]

|[[Allgemeines Deutsches Kommersbuch:2|2]]
|2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM