struct中的cin和char数组指针

时间:2012-04-09 21:30:51

标签: c++ arrays pointers struct cin

作为一名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”的指针,它应该可以使它工作。我的理解是否已经结束?

提前致谢 丹

5 个答案:

答案 0 :(得分:4)

我马上就看到了四个问题:

第1期

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函数混合在一起会导致奇怪的行为,而剩下的{{1}来自CR进入>>来电。您可以使用全部getline()(缺点:您在阅读make时没有强制执行>>限制)或全部200(缺点:您必须使用字符串缓冲区然后将它们转换为汽车数量和年份),或者在每次调用cin.getline()后放置cin.ignore(),如下所示:

>>

cin >> num;
cin.ignore();

同样,所有信用都归@Ben C所有,首先注意到这一点。

最后但并非最不重要

按照惯例,类/结构具有大写名称,变量具有小写/大写名称。考虑将cin >> Cars[i].manfYear; cin.ignore(); struct重命名为car,将数组从Car重命名为Cars。换句话说,你现在拥有的资本化逆转。

最后,我同意所有其他海报:您应该考虑使用cars代替string数组。

答案 1 :(得分:2)

首先,使用string代替差的旧C char[]

下一步:您不希望char * make[200];。你想要char make[200];char * make[200]是一个包含200个char指针的数组,可以用作200个以空字符结尾的字符串 - 但是,每个字符串必须new[]。只需使用char make[200];cin.getline(Cars->make, 200);

答案 2 :(得分: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 - 这只会指向数组的第一个元素。我假设你不想要那个;根据{{​​1}}使用下标语法将访问数组中的单个car对象。 (请记住,数组索引从零开始! - 实际上,你的 for 循环变量从零开始实际上会更加惯用)

2)警惕Cars[i-1].manfYearstd::getline符号一起工作的方式。 >>(流提取运算符)经常会留下任何换行符,这意味着您可能会在调用getline时看到“奇怪”的行为。如果你将两者混合在一起,那么使用像>>之类的东西可以帮助你丢弃换行符。

答案 3 :(得分:1)

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

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

只需将char* make[200]更改为char make[200],将*Cars->make更改为Cars[i].make

答案 4 :(得分:1)

首先,C ++中的数组是从0..n-1索引的,所以你的循环需要从

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

其次,您已将make声明为指针的200元素数组char;这很可能你想要什么。如果make应该存储字符串,请将其声明为char的简单数组:

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]的类型为car,而不是car *