在C++中比较字符的方法

6
这是我从中提取数据的文本文件。
10
wood      8
gold      7
silver    5
gold      9
wood      1
silver    1
silver    9
wood      3
gold      5
wood      7

我需要找到同名商品并将它们的数量相加,因此最终结果应该是木材=19;黄金=21;白银=15。这是我迄今为止所做的。

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    ifstream read("data.txt");
    int n;
    read >> n;
    char name[10][n]; // 10 symbols are given for items name
    int amount[n];
    for(int i=0; i<n; i++)
    {
    read.ignore(80, '\n');
    read.get(name[i], 10);
    read >> amount[i];
    }

for(int i=0; i<n; i++)
{
    for(int d=1; d<n; d++)
    {
    if(name[i]==name[d] && i!=d)
    {

    }
    }
}
    return 1;
}

到目前为止,问题在于name[i]==name[d]即使例如name[i]="wood"name[d]="wood"也不会有反应。

6
如果您使用std::string代替char[],您将感激不已。 - NathanOliver
4个回答

6
在C++中,我们倾向于使用std::string而不是char[]。前者重载了等号运算符,因此您的代码将可以正常工作。对于后者,您需要使用strcmp()来实现目标。
现在您的代码可能如下所示(我使用了std::vector,但您可以使用字符串数组,但我不建议这样做):
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

int main()
{
    ifstream infile("data.txt");
    int n;
    infile >> n;
    vector<string> name(n);
    int amount[n], i = 0;
    while (infile >> name[i] >> amount[i])
    {
        cout << name[i] << " " << amount[i] << endl;
        i++;
    }
    // do your logic
    return 0;
}

顺便提一下,您可以使用std::pair来使您的代码更易读,其中第一个成员将是名称,第二个成员将是数量。

与你的问题无关,main()通常在一切正常时 tend to return 0;,而你返回了1。

附注:这里有一个工作示例:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <utility>

using namespace std;

int main()
{
    ifstream infile("data.txt");
    int n;
    infile >> n;
    vector<string> name(n);
    int amount[n], i = 0;
    while (infile >> name[i] >> amount[i])
    {
//        cout << name[i] << " " << amount[i] << endl;
        i++;
    }


    vector< pair<string, int> > result;
    bool found;
    for(int i = 0; i < name.size(); ++i)
    {
        found = false;
        for(int j = 0; j < result.size(); ++j)
        {
            if(name[i] == result[j].first)
            {
                result[j].second += amount[i];
                found = true;
            }
        }
        if(!found)
        {
            result.push_back({name[i], amount[i]});
        }
    }

    cout << "RESULTS:\n";
    for(int i = 0; i < result.size(); ++i)
        cout << result[i].first << " " << result[i].second << endl;
    return 0;
}

输出:

Georgioss-MacBook-Pro:~ gsamaras$ g++ -Wall -std=c++0x main.cpp 
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out 
RESULTS:
wood 19
gold 21
silver 15

我该如何从文件中读取字符串?如果我将char更改为string,那么在行read.get(name[i], 10);处会出现error: no matching function for call to 'std::basic_ifstream<char>::get(std::string&, int)的错误。 - Mahig Yahok
问题是我现在正在为学校考试做准备,我不知道我们是否被允许使用额外的库,所以我宁愿学习如何使这段代码在没有它们的情况下工作。 - Mahig Yahok
1
好的,@MahigYahok,你可以使用strcmp(),就像我在我的回答中提到的那样。 - gsamaras

1

好的,gcc已知支持它,但C ++不支持变长数组,因此这行代码:

char name[10][n]; // 10 symbols are given for items name

不符合标准,应该至少发出警告。

处理在运行时才知道维度的数组的C++方式是使用std::vector

但你真正的问题是,原始char数组和char指针都没有重载==运算符(对于数组或指针是不可能的),所以在name[i]==name[d]中实际上是比较地址,因为当数组用于表达式时会衰减为指向它们的第一个元素的指针。因此,你的测试与if (&name[i][0] == &name[d][0)相同,无法给出预期结果。

你可以使用strcmp比较空结束的char数组(也称为C字符串),或者更好地使用具有重载==运算符的std::string


0

你所使用的 char[] == 操作符是在比较指针值,而不是字符串比较值。也就是说,你正在比较内存中第一个字符的位置。

顺带提一下,char name[10][n]; 是无效的,因为 n 必须是编译时常量。我建议使用 std::vector 代替。


0

如果你只是想要添加数字,可以使用 unordered_map。它类似于 Java 中的哈希表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接