cin.getline()崩溃了程序

时间:2014-07-12 15:50:39

标签: c++ crash getline

我使用C ++相当新,所以我不完全确定我的程序出了什么问题。每次我运行它都会在cin.getline()之后崩溃,我在其他地方问过,但似乎并不是一个明显的原因,为什么它不会工作。该代码用于读取用户输入并将其存储在链接列表中,然后搜索或删除列表中的条目。

#include <iostream>
#include <cstring>

using namespace std;

struct node{
       char name[20];
       char age[4];
       node *next;
};

class personList{
      public:
             void add_person(char name[20], char age[4]);
             void remove_person(char name[20]);
             node *search_people(char name[20]);

      protected:
                void add_node(char name[20], char age[4]);
                void remove_node(char name[20]);
                node *search_nodes(char name[20]);
                node *root;
                node *position;        
};

void personList::add_person(char name[20], char age[4]){
     add_node(name, age);
}

void personList::add_node(char name[20], char age[4]){
     if (position == NULL)
     {
                 root = new node;
                 strcpy(root->name, name);
                 strcpy(root->age, age);
                 root->next = NULL;
                 position = root;
     }
     else
     {
                position->next = new node;
                position = position->next;
                strcpy(position->name, name);
                strcpy(position->age, age);
                position->next = NULL;
     }
}

void personList::remove_person(char name[20]){
     remove_node(name);
}

void personList::remove_node(char name[20]){
     node *targ;
     targ = search_nodes(name);
     if (targ != NULL)
     {
              delete targ;
     }
}

node *personList::search_people(char name[20]){
     position = root;
     return search_nodes(name);
}

node *personList::search_nodes(char name[20]){
    while(strcmp(position->name, name) !=0 && position->next != NULL)
    {
                          position = position->next;
    }
    if (strcmp(position->name, name) == 0)
    {
                        return position;
    }
    else
    {
        return NULL;    
    }
}

int main(){
    personList database;
    int inp = 1;
    char name[20];
    char age[4];
    node *search_result;
    while (inp != 4)
    {
          cout << "list of commands:\n1. add person\n2. remove person\n3.search for person\n4. exit\n> ";
          cin.get() >> inp;
          switch (inp)
          {
                 case 1:
                      cout << "input the name and age of the person you wish to add:\n";
                      cin.getline(name, 20, '\n');
                      strcat(name, "\n");
                      cin.getline(age, 4, '\n');
                      strcat(age, "\n");
                      database.add_person(name, age);
                 case 2:
                      cout << "input the name of the person you wish to remove:\n";
                      cin.getline(name, 20, '\n');
                      database.remove_person(name);
                 case 3:
                      cout << "input the name of the person you wish to search for:\n";
                      cin.getline(name, 20, '\n');
                      search_result=database.search_people(name);
                      if (search_result == NULL)
                      {
                                        cout << "the person you searched for does not exist in this database\n";
                      }
                      else
                      {
                          cout << name << " is in the database as being " << search_result->age << " years old";
                      }
                 case 4:
                      break;
                 default:
                         cout << "bad input, please enter a number";
          }
    }      
}

据我所知,当我运行它时,它是第一个底部的第一个cin.getline()。只要我按下返回键,程序就会崩溃。

         case 1:
              cout << "input the name and age of the person you wish to add:\n";
              cin.getline(name, 20, '\n'); //this line causes the crash
              strcat(name, "\n");          //as far as I understand
              cin.getline(age, 4, '\n');
              strcat(age, "\n");
              database.add_person(name, age);

关于我做错事情的一般指示将非常感激。

谢谢!

2 个答案:

答案 0 :(得分:2)

这是您的代码的重要部分:

char name[20];
//...
cin.getline(name, 20, '\n');
strcat(name, "\n");

cin.getline名称后可以包含20个字符,包括终止空字符。所以你不能只为它添加另一个"\n",因为buffersize只有20而不是21。

除此之外,如果您的计划到达

database.add_person(name, age);

出了别的问题;你调用add_node,就像这样开始:

void personList::add_node(char name[20], char age[4]){
    if (position == NULL)

Bug position永远不会被初始化,personList甚至没有构造函数,因此它可能不会为null,但也无效。

答案 1 :(得分:1)

除了已经说过的关于修复当前设计中的错误的内容之外:

缺少流读取也可以使用std :: string作为目标来完成,这使得用户免受char指针voodoo的影响,这是一个常见的初学者疏忽。

不仅仅是

// http://en.cppreference.com/w/cpp/io/basic_istream/getline
std::istream::getline(char*, /*[...]*/) 

但您也可以使用

// [...]
#include <string>
// [...]
// given
// std::string s
// std::istream is
// somewhere
//
// http://en.cppreference.com/w/cpp/string/basic_string/getline
std::getline(is, s);

位于<string>。 如果人们担心缓冲区重新分配造成的任何开销,可以在流读取之前使用s.reserve(N)一次,并使用合理的N值。