2

私は学校の課題に取り組んでいますが、その一部で少し行き詰まっています。分子に0が入力されるまで、ユーザーに必要な数の分数を入力してもらい、それらの分数を作成した構造に保存する必要があります。

ユーザー入力をスペースで保存し、次に「/」で保存するために使用するc文字列をstrtokで分割しようとしましたが、非常に行き詰まり、適切な出力を取得できませんでした(以下のコードはmain( )実行時エラーがあり、2番目のforループは明らかにdenに適切なものを割り当てるのに失敗します)。

これを達成するための最も簡単な方法は何でしょうか。

#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
struct Fraction 
{
    int num, den;
};
int main()
{
    Fraction* fractions[100];
    char s[100] ;
    cout << "Enter fractions (end by entering a 0): ";
    cin >> s;
    const char* p;
    int count = 0;

    for (p = strtok( s, " " );  p;  p = strtok( NULL, "," ))
    {
        const char* frac = p;
        for (frac = strtok( s, " " );  frac;  frac = strtok( NULL, "/" ))
        {
            fractions[count]->num = (int)frac;
        count++;    
        }
    }
        return 0;
}
4

2 に答える 2

4

最初の(実行時)エラーは、
Fraction* fractions[100];

これは、Fractionオブジェクトへのポインタの配列です。ただし、Fractionオブジェクト自体が作成/初期化されることはありません。

これにより、セグメンテーション違反が発生しますfractions[count]->num = (int)frac;

これはいくつかの方法で修正できます。
1.
Fraction fractions[100];他の答えによって示唆されたように。
最も単純です。他の変更は、に変更すること->だけ.ですfractions[count]->num = (int)frac;

効率的になり、必要な数のオブジェクトのみを作成する場合は、2つの方法があります。
2a。
Fraction* fractions[100] = null;
fractions[count] = new Fraction(atoi(frac));
ヒープに割り当てているため、delete完了時に使用する各オブジェクトに割り当てる必要があります

2b。
std::vector<Fraction> fractions; fractions.push_back(Fraction(atoi(frac))); よりC++っぽい選択。ベクトルは(単純に)必要に応じて自動的に大きくなる配列であるため、事前に最大サイズを必要としません。オブジェクトのベクトルを作成しているので、それらも必要ありませんdelete


2番目のエラーは(int)frac;です。私はあなたが欲しいと信じていますatoi(frac)。前者はあなたが望まない文字のポインタアドレスをあなたに与えるでしょう、一方後者は文字列を数字に正しく解析するでしょう


私はあなたが内側のループを必要としないと思います(基本的な分数のために)。ちょうど以下が行う必要があります。ユーザーがの形式で入力すると仮定します,<space><num>/<den><space>,。それ以外の場合は、入力文字列を変更するため、strtokの使用には注意してください。それはあなたのコードの問題でさえあるかもしれません..(編集)安全のために、ネストされたstrtok呼び出しを削除しました。

fractions.push_back(Fraction(atoi(strtok(NULL,"/"),atoi(strtok(NULL," "))))


@Xymostechの入力コードを編集すると、はるかにクリーンになり、の機能に関する誤解も修正されますcin。あなたは彼のバージョンに従うことができます。

于 2012-11-26T02:46:23.703 に答える
4

あなたはしたくない

Fraction* fractions[100];

あなたはただ欲しい

Fraction fractions[100];

1つ目はsへのポインタFractionsの配列で、2つ目は単なるの配列ですFractions。おそらくあなたが抱えている問題は、ポインタを初期化しなかったことです。

さらに良いアプローチは、を使用してstd::vector<Fraction>を保存することFractionです。次に、動的に追加して、必要な数Fractionのを保存できます。


あなたが持っているもう一つのエラーはあなたが値を読んでいる方法です。電話するとき

cin >> s;

完全な行では読み取られず、単一のトークンのみが読み取られます。また、分数の分子のみを設定しているだけです。したがって、2つのオプションがあります。

  1. 、を使用getlineして全行を読み取り、そこから解析します。

  2. より効果的に使用cin >>し、次のようなことを行います。

-

while (cin >> s)
{
    char* frac = s;

    if (!strcmp(s, "0")) break;

    char* num = strtok( frac, "/" );
    char* denom = strtok( NULL, "/");

    fractions[count].num = atoi(num);
    fractions[count].den = atoi(denom);
}
于 2012-11-26T02:46:35.540 に答える