从文件中查找单词并替换为其他文件

问题描述 投票:0回答:2

我有两个这样的文本文件:11.txt:

1 5.66
2 4.95
3 2.55
4 0.99
5 2.87

NB.txt:

1 2 3 4 5
4 5 3 2 1
3 4 5 1 2

我已经编写了下面的代码,例如,从文件1中选择“ 1”,然后在文件2中进行搜索,然后将“ 1”替换为“ 5.66”。并重复其他数字,即2,3,4,5。但我不知道为什么它不起作用。此外,它不会读取11.txt的第一行。

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main () 
{
    string  line;
    double AtomId, Atom_radius,search ;

    ifstream AtomId_file ("11.txt");
    string namefile;
    if (AtomId_file.is_open()){
        for (int linenox = 0; getline (AtomId_file,line) && linenox < 6; linenox++){
            if (linenox == 0)  AtomId_file>>AtomId>>Atom_radius;
            }
        cout<<"AtomId: "<<AtomId<<" Atom_radius: "<<Atom_radius<<endl;
        cout<<namefile<<"\n";

    }

    ifstream NB("NB.txt");

    size_t pos;
    if (NB.is_open())
      {     
          search = AtomId;
          getline(NB,line); 
          pos=line.find(search);
          if(pos!=string::npos) 
            {
                search = Atom_radius;
                cout <<"Found!";
            }
      } 

    ofstream myfile;
    myfile.open ("12.txt");
    myfile << search << "\n";
}

12.txt中的输出是:

2

而不是:

5.66 4.95 2.55 0.99 2.87
0.99 2.87 2.55 4.95 5.66
2.55 0.99 2.87 5.66 4.95
c++ file substitution
2个回答
1
投票

我了解您是C ++的新手。

我分析了您的代码,并在错误所在的地方添加了大量注释。您需要更改设计。在开始键入代码之前,您必须先写下,what应该完成。然后,这是最重要的,您认为(不考虑任何语言)如何就可以解决问题。这是最重要的。也适合您以后的编程生涯。 design最重要。因此,请考虑3个小时,该怎么做。在互联网上搜索可能的设计解决方案。将其写在纸上或其他地方。

然后,经过数小时的思考,选择一种合适的语言并检查其实施方式。

我在下面显示了标准的C ++解决方案。您不会立即了解它。因此,请首先尝试理解design。然后在互联网上查找所有使用过的C ++语句并尝试理解。

在开始编写代码之前,请阅读一些不错的C ++书籍。

请先查看您的注释代码:

#include <iostream>
#include <fstream>
#include <string>
using namespace std;    // You should not use this line at all. Use qualified names.

int main()
{
    string  line;
    double AtomId, Atom_radius, search;  // These variables are not initalized

    ifstream AtomId_file("r:\\11.txt");
    string namefile;
    if (AtomId_file.is_open()) {   // You should not use is_open but simply   if (AtomId_file)

        // Here you have a loop running from 0,1,2,3,4,5. That are 6 loops. But you have only 5 lines in your sourcefile
        // The you read one line, each time the loops runs. So in the beginning, this will read the first line
        for (int linenox = 0; getline(AtomId_file, line) && linenox < 6; linenox++) {
            // And only for the first loop event, when linenox==0, you read then next line "2 4.95"
            // So you read already lines. But not more.
            // ypu need to read line by line (only one per loop) and then store the result in an appropriate STL Container
            if (linenox == 0)  AtomId_file >> AtomId >> Atom_radius;
        }

        // Since you assigned the data only once, the values will be 2, 4.95
        // They will never change
        cout << "AtomId: " << AtomId << " Atom_radius: " << Atom_radius << endl;
        // The variable namefile has never been initailized and is always emtpy, So ""
        cout << namefile << "\n";

    }

    ifstream NB("r:\\NB.txt");

    size_t pos;  // Not initialized
    if (NB.is_open())  // Not recommended. Use "if (NB) instead". In general, use more meaningful variable names
    {
        search = AtomId;   // search is now 2 and never somthing else
        getline(NB, line); // Read exactly one (and only this one time) a line containing 1,  5.66
        pos = line.find(search);  // So, 2 will never be found
        if (pos != string::npos)   // Always false, can never be true
        {
            search = Atom_radius;   // Will never be executed
            cout << "Found!";       // Will never be executed
        }
    }

    ofstream myfile;  // You can write directly  ofstream myfile("12.txt");
    myfile.open("12.txt"); 
    myfile << search << "\n";  // And the output will always be 2.
}

这是一个正确且有效的示例:

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <unordered_map>
#include <vector>
#include <iterator>

int main() {

    // Open the file 11.txt and check, if it could be opened
    if (std::ifstream file11("11.txt"); file11) {

        // Define variable id and attribute and initialize them to theire default values.
        unsigned int id{};
        double attribute{};

        // Here we will store all values (id, attribute) of all lines that we read in the follwing loop
        std::unordered_map<unsigned, double> replacement{};

        // Read in a llop ALL lines and extract id and attribute, and, check if this worked
        while (file11 >> id >> attribute) {
            // Create a new replacement value for id
            replacement[id] = attribute;
        }
        // So, now, all data from file 11.txt is read and stored.
        // We will now read the next file and store the data

        // Open next input file NB.txt and check, if that worked
        if (std::ifstream fileNB("NB.txt"); fileNB) {

            // And already now, open output file 12.txt and check, if open worked
            if (std::ofstream myfile("12.txt"); myfile) {

                // Read a complete line and check, if that worked. Read all lines in a loop
                for (std::string line; std::getline(fileNB, line); ) {

                    // Put the line in a std::istringstream, so that we can extract each single value
                    std::istringstream iss(line);

                    // We will store the single values of the just read line into a vector
                    // This we do, because we do not know, how many values will be in that line
                    // We use a so called iterator, to iterate over all elements in the just read line
                    // The result will be stored in a vector
                    // The istream_iterator will call the ">>"-operator, until the line is empty
                    // For the vector, we use its range constructor
                    std::vector values(std::istream_iterator<unsigned>(iss), {});

                    // Now go through all values, replace them and out the result into the output file
                    for (const unsigned& u : values)    myfile << replacement[u] << " ";
                    myfile << "\n";
                }
            }
        }
    }
    return 0;
}

当然还有许多其他可能的解决方案


0
投票
  1. [打开文件时,请指定文件的完整路径,并始终检查文件是否<:

    ifstream is11{ "c:/temp/11.txt" }; if (!is11) return cout << "could not open input", -1;
  2. 输入文件由

    索引和值组成。这应该使您认为“向量/数组”。读取索引和值,然后将值存储在std::vector中。如果您不知道如何使用它,只要输入文件中的索引在限制范围之内,plain array就足够了–如果文件中的最大索引为10,则为数组大小必须至少为11。

    double input[1024]; int idx; double value; while (is11 >> idx >> value) // while we can read input[idx] = value;
  3. 打开第二个输入文件和输出文件。读取向量/数组中的索引

    寻找值并将其写入。

    while (isnb >> idx) os12 << input[idx] << ' ';
© www.soinside.com 2019 - 2024. All rights reserved.