getline()使程序崩溃

cin.getline() crashes the program

本文关键字:程序 崩溃 getline      更新时间:2023-10-16

我对使用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 personn2. remove personn3.search for personn4. exitn> ";
          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 databasen";
                      }
                      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);

如果你能指出我做错的地方,我将不胜感激。

谢谢!

这是代码的重要部分:

char name[20];
//...
cin.getline(name, 20, 'n');
strcat(name, "n");
cin.getline名称后的

可以包含20个字符,包括终止null字符。所以你不能再加一个"n",因为缓冲区大小是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甚至没有构造函数,所以它可能不是空的,但也无效

除了已经说过的修复当前设计中的错误:

忽略流读取也可以使用std::string作为目标来完成,这将使用户从char指针的束缚中解放出来,这是初学者常见的疏忽。

不只是

// 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设置一个合理的值