2

我正在做一项学校作业,其中一部分让我有点卡住了。我需要让用户根据需要输入尽可能多的分数,直到为分子输入 0,并将这些分数保存在我创建的结构中。

我试图让我们 strtok 将用于存储用户输入的 c 字符串按空格,然后按“/”,但我非常卡住,无法获得任何正确的输出(下面的代码是 main( ) 它有一个运行时错误,并且第二个 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个。
Fraction* fractions[100] = null;
fractions[count] = new Fraction(atoi(frac));
您在堆上分配,因此需要在delete完成后使用的每个对象

2 乙。
std::vector<Fraction> fractions; fractions.push_back(Fraction(atoi(frac))); 更多的 C++ -ish 选择。Vector是(简单地说)一个数组,它会根据需要自动变大,因此不需要预先设置最大大小。由于您正在制作对象的矢量,因此您也不需要delete它们。


你的第二个错误是(int)frac;. 相信你想要atoi(frac)。前者会给你你不想要的字符的指针地址,而后者会正确地将字符串解析成一个数字


我认为您不需要内部循环(对于基本分数)。只是下面应该做的。假设用户输入的格式是,<space><num>/<den><space>,. 否则请谨慎使用 strtok,因为它会修改输入字符串。甚至可能是您的代码的问题..(编辑)为了安全起见,删除了嵌套的 strtok 调用。

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

编辑
@Xymotech 的输入代码更加简洁,也修正了对cin. 你可以按照他的版本。

于 2012-11-26T02:46:23.703 回答
4

你不想

Fraction* fractions[100];

你只想

Fraction fractions[100];

第一个是指向 s 的指针数组,第二Fractions个只是Fractions. 您可能遇到的问题是您没有初始化指针。

更好的方法可能是使用 astd::vector<Fraction>来存储您Fraction的 s。然后,您可以动态添加到它,它可以存储Fraction您需要的任意数量的 s。


您遇到的另一个错误是您读取值的方式。你打电话时

cin >> s;

它不会读取整行,只有一个标记。此外,您只需要设置分数的分子。因此,您有两个选择:

  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 回答