【问题标题】:Segmentation fault while unpacking data from file ( using strtok() and strcpy() )?从文件中解包数据时出现分段错误(使用 strtok() 和 strcpy() )?
【发布时间】:2017-09-15 05:34:52
【问题描述】:

在我为学校作业编写的代码方面需要帮助。

程序从用户那里获取学生数据并将其写入名为“学生数据”的文件中。写入文件工作正常。数据写入正确。 但是当从文件中读取数据时,我会遇到分段错误。我正在尝试使用 strtok() 来跳过不需要的字符。 调试后发现问题出在 unpack 函数上。故障发生在 void unpack() 的第一行。

这是一个非常基本的程序。我真的需要从文件中读取数据来执行搜索、更新和删除等操作。

抱歉,如果这是一个非常明显的错误。我尝试了很多事情,包括搜索相关问题。没有什么对我有用。如果你们能看一看,我将不胜感激。请帮帮我。谢谢。

还请用简单的术语解释我做错了什么。

#include<iostream>
#include<fstream>
#include<string.h>
#include<iomanip>

using namespace std;

const int buffSize=250;

class StudentData
{
       char rollNo[12];
       char firstName[16];
       char secondName[16];
       char division[8];
       char address[32];
       char buffer[buffSize];

       //makes data more readable and copies it to buffer,buffer written as      it is into a file
       void pack()
       {
              strcpy(buffer,"| ");
              strcat(buffer,"ROLL NO: ");
              strcat(buffer,rollNo);
              strcat(buffer," ");

              strcat(buffer,"| ");
              strcat(buffer,"NAME: ");
              strcat(buffer,firstName);
              strcat(buffer," ");
              strcat(buffer,secondName);
              strcat(buffer," ");

              strcat(buffer,"| ");
              strcat(buffer,"DIVISION: ");
              strcat(buffer,division);
              strcat(buffer," ");

              strcat(buffer,"| ");
              strcat(buffer,"ADDRESS: ");
              strcat(buffer,address);
              strcat(buffer," ");

              strcat(buffer," |");
       }

       //data from file is available in buffer, copied into respective     variables for display
       void unpack()
       {
              strtok(buffer," ");
              strtok(NULL," ");
              strtok(NULL," ");
              strcpy(rollNo,strtok(NULL," |"));

              strtok(NULL," ");
              strtok(NULL," ");
              strcpy(firstName,strtok(NULL," "));
              strcpy(secondName,strtok(NULL," |"));

              strtok(NULL," ");
              strtok(NULL," ");
              strcpy(division,strtok(NULL," |"));

              strtok(NULL," ");
              strtok(NULL," ");
              strcpy(address,strtok(NULL," |"));
       }


   public:

       //add data to file
       void add_data()
       {
              cout<<"Enter Roll No: ";
              cin>>rollNo;

              cout<<endl;

              cout<<"Enter Name of student: ";
              cin>>firstName;
              cin>>secondName;

              cout<<endl;

              cout<<"Enter Division of student: ";
              cin>>division;

              cout<<endl;

              cout<<"Enter Address of student: ";
              cin>>address;

              cout<<endl;

              //pack data
              pack();

              //create ofstream object for writing in file
              ofstream outFile;

              //open in append mode
              outFile.open("Student Data",ios::app);
              //write contents of buffer to file and a new line
              outFile<<buffer<<endl;
              //close file
              outFile.close();

              cout<<"Data successfully added to file...!"<<endl;

       }


       void display()
       {
              cout<<"-------------------------------------------"<<endl;
              cout<<endl;
              cout<<"**********Student Information************"<<endl;
              cout<<"-------------------------------------------"<<endl;
              cout<<endl;

              cout<<setw(12)<<"Roll No";
              cout<<setw(30)<<"Name";
              cout<<setw(30)<<"Division";
              cout<<setw(30)<<"Address";
              cout<<endl;

              //create ifstream object to read from file
              ifstream inFile;
              //open file
              inFile.open("Student Data");

              while(!inFile.eof())
              {
                    //read data from file into buffer
                    inFile>>buffer;

                    if(inFile.fail())
                    {
                         cout<<"File failed to open"<<endl;
                         break;
                    }

                    unpack();

                    cout<<rollNo<<setw(12);
                    cout<<firstName<<setw(14);
                    cout<<secondName<<setw(1);
                    cout<<division<<setw(30);
                    cout<<address<<setw(30);

                }

                //close file
                inFile.close();

         }

   };


   int main()
   {
       StudentData s;
       s.add_data();
       s.display();

       return 0;
   }

【问题讨论】:

    标签: c++ string file-handling


    【解决方案1】:

    strtok 如果找不到更多标记,则返回空指针,因此在使用它之前应始终检查返回值。

    您的代码的另一个问题是您使用小缓冲区从 std 输入读取,例如 cin&gt;&gt;rollNo;,因为写入不知道缓冲区大小,它可能会溢出并损坏内存,因此您应该使用 std::stringistream::get 代替。

    【讨论】:

    • strcpy(address,strtok(NULL," |")); - 当strtok 返回 NULL 时会崩溃。
    猜你喜欢
    • 2021-03-14
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 2020-04-20
    • 2014-12-21
    • 2018-02-07
    • 2018-03-17
    相关资源
    最近更新 更多