1

作为一个 c++ 初学者,我编写了以下代码:

int main(void){
struct car{
    char * make[200];
    int manfYear;
};

int num=0;

cout << "How many cars do you wish to catalogue? ";
cin >> num;
car * Cars = new car [num]; 

for (int i=1;i<=num;i++){
    cout << "Car #" << i << ":" << endl << "Please enter the make: ";
    cin.getline(*Cars->make,200);
    cout << "Please enter the year made: ";
    cin >> Cars->manfYear;
}

我的问题是我无法解决一个问题,即在我需要输入汽车模型的地方运行程序时出现段错误。有人可以解释我做错了什么吗?

据我了解,我正在传递一个指向数组“make”的指针,它应该使它工作。我的理解有偏差吗?

提前感谢丹

4

5 回答 5

4

我马上看到的四个问题:

第一期

在您的struct中,您有:

char * make[200];

在英语中,这就是“创建一个包含 200 个字符的指针的数组”,而我认为您想说的是“创建一个包含 200 个字符的数组”。所以你应该改为:

char make[200].

第 2 期

您从 开始循环1。这将跳过数组中的第一辆车——记住数组是零索引的。所以你应该改为:

for (int i = 0 ; i < num ; i++)

出于显示目的,您可以说:

cout << "Car #" << (i+1) << ":" << endl << "Please enter the make: ";

第 3 期

你说的地方:

cin.getline(*Cars->make,200);

cin >> Cars->manfYear;

您在这些行中的哪个位置指定了用户正在使用的汽车?无处。如果您正在循环使用i,那么您实际上需要提及i. 这些应该工作:

cin.getline(Cars[i].make,200);

cin >> Cars[i].manfYear;

请注意,我们使用的是.,而不是->。这是因为Cars数组中的项目是实际实例,而不是指针。Cars数组本身是一个指针,但不是它的内容。

第 4 期

所有功劳归功于@Ben C,他首先指出了这一点:将>>运算符与getline()函数混合在一起cin会导致奇怪的行为,剩余CR>>会进入getline()调用。您可以使用 all >>(缺点:在阅读 make 时没有200强制执行限制)或 all cin.getline()(缺点:您必须使用字符串缓冲区,然后将它们转换为汽车数量和年份),或者cin.ignore()在每次调用之后放置的>>,像这样:

cin >> num;
cin.ignore();

cin >> Cars[i].manfYear;
cin.ignore();

再次感谢@Ben C首先注意到这一点。

最后但并非最不重要的

按照惯例,类/结构具有大写名称,而变量具有小写/驼峰式名称。考虑重命名structfrom cartoCar和数组 from Carsto cars。换句话说,与您现在的大小写相反。

最后,我同意这里的所有其他海报:您应该考虑使用string而不是char数组。

于 2012-04-09T21:49:41.340 回答
2

首先,使用string而不是可怜的旧 C char[]

下一个:你不想要char * make[200];. 你想要char make[200];char * make[200]是一个包含 200 个指向chars 的指针的数组,它可以用作 200 个以 null 结尾的字符串 - 但是,您必须对new[]它们中的每一个都进行处理。只需使用char make[200];cin.getline(Cars->make, 200);

于 2012-04-09T21:34:42.060 回答
2

char * make[200]声明一个包含 200 个指针的数组;我猜这不是你想要的。

如果您只是想存储一个字符串,我建议您查看 C++string类型。

#include <iostream>
#include <string> 

int main()
{
    using namespace std;

    struct car
    {
        string make;
        int manfYear;
    };

    int num=0;

    cout << "How many cars do you wish to catalogue? ";
    cin >> num;
    car * Cars = new car [num]; 

    for (int i=1;i<=num;i++)
    {
        cout << "Car #" << i << ":" << endl << "Please enter the make: ";
        std::cin.ignore();
        getline(cin, Cars[i-1].make);
        cout << "Please enter the year made: ";
        cin >> Cars[i-1].manfYear;
    }
}

您的代码还有其他一些小问题。

1)您一直在使用Cars->manfYear- 这只会将您指向数组的第一个元素。我假设你不想要那个;按照 per 使用下标语法Cars[i-1].manfYear将访问数组中的单个汽车对象。(请记住,数组索引从零开始!-实际上,对于您的for循环变量,从零开始实际上更符合习惯用法)

2)小心方式std::getline>>符号一起工作。(>>流提取运算符)通常会留下任何换行符,这意味着您可能会在调用 getline 时看到“奇怪”的行为。如果您将两者混合在一起,那么使用类似std::cin.ignore()的东西将帮助您丢弃换行符。

于 2012-04-09T21:43:36.830 回答
1

首先char *make[200]不是一个最多 200 个字符的字符串,而是 200 个指向char.

第二件事:您正在取消引用其中的指针:发生cin.getline*情况是您获得了 200 个char*指针的第一个单元格中包含的值。但是你没有初始化单个指针,只是更高级别的指针,所以你得到了一个段错误。

只需更改char* make[200]char make[200]和。*Cars->makeCars[i].make

于 2012-04-09T21:35:56.650 回答
1

首先,C++ 中的数组从 0..n-1 开始索引,因此您的循环需要从

for (int i = 0; i < num; i++) { ... }

其次,您已经声明了一个包含 200 个元素的指针make数组;这很可能不是您想要的。如果应该存储一个字符串,请将其声明为一个普通数组:charmakechar

struct car{
      char make[200];
      int manfYear;      
}; 

getline最后,将您的电话重写为

cin.getline(Cars[i].make, sizeof Cars[i].make); // fixed per comment below

即使Cars被声明为指针,您也可以在其上使用下标运算符,就好像它是一个数组一样;通过这样做,您隐式取消引用Cars,因为a[i]被解释为*(a + i). 这也意味着您将使用.组件选择运算符而不是->运算符,因为类型Cars[i]is car, not car *

于 2012-04-09T21:43:27.563 回答