如何比较两个单独文本文件中的两个不同字符串?

时间:2013-07-23 23:58:03

标签: c++ string compare iostream

我是一名c ++新秀,不知道我做错了什么。我的任务是比较两个不同的.txt文件,每个文件包含一个项目以及项目的数量和该项目的价格。然后我试图打印物品的名称和价格。假设我使用的是.txt文件namesAndQuantity.txt,其中包括:

3 books
4 pens

一个.txt文件namesAndPrice.txt,其中包括:

pens 3.45
books 19.55

我使用的代码只打印出第一场比赛:

#include <iostream>
#include <fstream>
#include <cmath>

int main(){
    string nameOfItemP, nameOfItemQ;
    double priceOfItem;
    int numberOfItems;
    ifstream inData;
    ifstream inData2;
    inData.open("namesAndQuantity.txt");
    inData2.open("namesAndPrice.txt");
    while (inData>>numberOfItems>>nameOfItemQ){
        while (inData2>>nameOfItemP>>priceOfItem){
            if (nameOfItemP==nameOfItemQ){
               cout<<nameOfItemQ<<endl;
               cout<<priceOfItem;
        }   
    }
}

此代码仅打印出第一行:

books
19.55

我能做些什么来改善它?

3 个答案:

答案 0 :(得分:2)

这是因为在第一次

之后
while (inData2>>nameOfItemP>>priceOfItem){
    if (nameOfItemP==nameOfItemQ){
        cout<<nameOfItemQ<<endl;
        cout<<priceOfItem;
    }   

执行,inData2到达终点,不再阅读。解决方案是将open函数移动到while循环:

while (inData>>numberOfItems>>nameOfItemQ){
    inData2.open("namesAndPrice.txt");
    while (inData2>>nameOfItemP>>priceOfItem){
        if (nameOfItemP==nameOfItemQ){
           cout<<nameOfItemQ<<endl;
           cout<<priceOfItem;
    }
    inData2.close();  
}

但是,这不是最好的方法。您最好使用map来避免嵌套循环。 map类似于数组,但您可以选择使用string作为索引:

#include <iostream>
#include <fstream>
#include <string>
#include <map>

using namespace std;

int main() {
    // same as before
    int numberOfItems;
    string nameOfItem;
    double price;

    // create a map, using string as index and int as value.
    map<string, int> items;

    ifstream inData("namesAndQuantity.txt");
    ifstream inData2("namesAndPrice.txt");

    while (inData >> numberOfItems >> nameOfItem)
      items[nameOfItem] = numberOfItems;

    while (inData2 >> nameOfItem >> price)
      cout << nameOfItem << " "
           << items[nameOfItem] << " " << price << endl;

    inData.close();
    inData2.close();

    return 0;
}

输出

pens 4 3.45
books 3 19.55

答案 1 :(得分:0)

你有两个while循环,第一个是好的,但第二个while循环将在执行第一个priceofItem查找后终止。它将遍历整个文件以结束第一次查找。当下一次迭代尝试从外部while循环执行时,内部循环为FALSE,其类似于while(false)。 你需要的是一个存储,一个Arraylist,它将存储项目的名称和价格。这将提供从I = 0到I = n的多次迭代。

答案 2 :(得分:0)

我认为@Yang至少有一些正确的一般性想法,但我认为我的做法有点不同。他的代码只适合读取数据并完全按照此处的规定显示。我宁愿看到一些具有更多通用适用性的代码,例如存储所有数据,如果(例如)你想要以不同的格式打印它或者在打印之前过滤它,那将更加实用。考虑到这一点,我会更像这样编写代码:

#include <iostream>
#include <string>
#include <map>
#include <algorithm>
#include <vector>
#include <iterator>
#include <fstream>

struct item {
    int quantity;
    double p;

    friend std::ostream &operator<<(std::ostream &os, item const &j) {
        return os << "\t(" << j.quantity << ")\t$" << j.p;
    }
};

std::ostream &operator<<(std::ostream &os, std::pair<std::string, item> const &r) {
    return os << r.first << ":" << r.second;
}

void read_quantities(std::string const &fname, std::map<std::string, item> &items) {
    std::ifstream in{ fname };
    std::string name;
    int temp;
    while (in >> temp >> name)
        items[name].quantity = temp;
}

void read_prices(std::string const &fname, std::map<std::string, item> &items) {
    std::ifstream in{fname};
    std::string name;
    double temp;
    while (in >> name >> temp)
        items[name].p = temp;
}

int main() {
    std::map<std::string, item> items;

    read_quantities("quantities.txt", items);
    read_prices("prices.txt", items);

    for (auto const & item : items)
        std::cout << item << "\n";
}

我也更喜欢保持一些关注点的分离 - 一个函数通常应该只有一个...函数。例如,我更喜欢只读取的读取代码和只写入的代码,而不是单个函数获取一些现有数据,从文件中读取更多数据,然后写出现有数据的组合新数据。

这并不是说后者是可怕的或可怕的或类似的东西 - 只是因为我更喜欢来限制每个功能在合理的时候做一件事。