web-dev-qa-db-ja.com

C ++でのcharの比較

これは私がデータを取得している私のテキストファイルです

10
wood      8
gold      7
silver    5
gold      9
wood      1
silver    1
silver    9
wood      3
gold      5
wood      7

同じ名前の商品を見つけてすべての金額を加算することになっているので、最終結果はwood = 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
Mahig Yahok

C++では、_std::string_よりも _char[]_ を使用する傾向があります。 1つ目は、等式演算子がオーバーロードされているため、コードは機能します。後者の場合、目標を達成するには 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_ を使用して、コードを読みやすくすることができます。最初のメンバーは名前、2番目のメンバーは金額になります。


問題とは関係なく、main()は、すべてが正常な場合は_return 0;_になる傾向がありますが、1を返します。

PS:これが実際の例です:

_#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
_
6
gsamaras

わかりました。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を使用してnullで終了するchar配列(C文字列とも呼ばれます)を比較するか、オーバーライドされた_std::string_演算子を持つ_==_を使用することをお勧めします。

1
Serge Ballesta

使用しているchar [] ==演算子は、文字列比較値ではなく、ポインタ値を比較しています。つまり、メモリ内の最初の文字の位置を比較しています。

ちなみに、char name [10] [n];無効です;そのnはコンパイル時定数でなければならないからです。代わりにstd :: vectorをお勧めします。

0
UKMonkey

番号を追加したいだけの場合は、 nordered_map を使用できます。これは、Javaのハッシュテーブルに似ています。

0
Vraj Pandya