簡體   English   中英

strcpy斷言錯誤C ++

[英]strcpy assertion error c++

我是一個學生,只是學習c ++,所以我確信有很多更有效的方法可以做到這一點。 如此說來,我真的很感謝能幫助我弄清楚程序為什么崩潰的幫助。 我將其范圍縮小了一個strcpy函數,該函數崩潰並破壞了所有內容,並對其進行了注釋和標記。 很明顯,我在程序中多次使用具有相似參數的strcpy函數,因此我不明白為什么該特定程序會崩潰。 我已經嘗試了所有我能想到的,並非常感謝您的幫助。 到目前為止,我有很多注釋,因此它應該與名為“ bookdb”的正確文本文件一起運行,我的文本文件當前包含該文件

Active Learning Approach,Randal Albert,9780763757236,1,650,1,<br>
Technical Communications,John Lannon,9780321899972,2,724,0,

要查看錯誤,您必須取消注釋strcpy(bookArray [num_books] .author_name,temp_authorName);

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>

enum Genres {HORROR=1, SCIFI, COMEDY, DRAMA, ACTION};


struct Book
{
    char title[100];
    char author_name[50];
    char isbn[14];
    Genres genre;
    int num_pages;
    bool paperback;
};

//Function Declarations
unsigned short ReadBooks(Book * bookArray, unsigned short & num_books);
void DisplayBooks(Book * bookArray, unsigned short num_books);
void ResizeArrays(Book * bookArray, unsigned short num_books);

int main ()
{
    unsigned short num_books = 0;
    Book * bookArray = new Book();

    num_books = ReadBooks(bookArray, num_books);

}//End Main

unsigned short ReadBooks(Book * bookArray, unsigned short & num_books)
{
    ifstream readBooks("bookdb.txt");
    char temp_title[100] = "0";
    char temp_authorName[100] = "0";
    char temp_isbn[14] = "0";

    char temp_genre[50] = "0";
    char temp_numPages[50] = "0";
    char temp_paperback[50] = "0";

    int genreNumber = 0,
        numPages = 0,
        paperback = 0;

    if (readBooks.is_open() )
    {
        cout << "The file was successfully opened\n" << endl;

        readBooks.getline(temp_title, 100, ',');//Reads into temp cstring
        strcpy(bookArray[num_books].title, temp_title); //copies to dynamic cstring
        //cout << bookArray[num_books].title << endl; //displays part of structure to make sure it worked!!

        readBooks.getline(temp_authorName, 100, ',');
        strcpy(bookArray[num_books].author_name, temp_authorName); 
        //cout << bookArray[num_books].author_name << endl; 

        readBooks.getline(temp_isbn, 14, ',');
        strcpy(bookArray[num_books].isbn, temp_isbn); 
        //cout << bookArray[num_books].isbn << endl;

        readBooks.getline(temp_genre, 50, ',');//Get the genre as a char
        genreNumber = atoi(temp_genre);//converts char to an int
        bookArray[num_books].genre = static_cast <Genres> (genreNumber);//converts int to ENUM
        //cout << bookArray[num_books].genre << endl;//Displays ENUM to make sure it worked!!

        readBooks.getline(temp_numPages, 50, ',');
        numPages = atoi(temp_numPages); //converts char to an int
        bookArray[num_books].num_pages = numPages; //assigns int to structure
        //cout << bookArray[num_books].num_pages << endl; //Displays part of structure to make sure to works!!

        readBooks.getline(temp_paperback, 50, ',');
        paperback = atoi(temp_paperback); //converts char to an int
        bookArray[num_books].paperback = static_cast <bool> (paperback);
        //cout << bookArray[num_books].paperback << endl;
        num_books++;

        //DisplayBooks(bookArray, num_books);
        ResizeArrays(bookArray, num_books);
        cout << "The number of books is: " << num_books << endl;

        //while (!readBooks.eof() )
        //{

        readBooks.getline(temp_title, 100, ',');//Reads into temp cstring
        strcpy(bookArray[num_books].title, temp_title); //copies to dynamic cstring
        cout << bookArray[num_books].title << endl; //displays part of structure to make sure it worked!!

        readBooks.getline(temp_authorName, 100, ',');
        cout << temp_authorName << endl; 
        //strcpy(bookArray[num_books].author_name, "0");
        ///THIS BREAKS MY CODE////strcpy(bookArray[num_books].author_name, temp_authorName); 
        //cout << bookArray[num_books].author_name << endl; 

        readBooks.getline(temp_isbn, 14, ',');
        //strcpy(bookArray[num_books].isbn, temp_isbn); 
        //cout << bookArray[num_books].isbn << endl;

        readBooks.getline(temp_genre, 50, ',');//Get the genre as a char
        //genreNumber = atoi(temp_genre);//converts char to an int
        //bookArray[num_books].genre = static_cast <Genres> (genreNumber);//converts int to ENUM
        //cout << bookArray[num_books].genre << endl;//Displays ENUM to make sure it worked!!

        readBooks.getline(temp_numPages, 1000, ',');
        //numPages = atoi(temp_numPages); //converts char to an int
        //bookArray[num_books].num_pages = numPages; //assigns int to structure
        //cout << bookArray[num_books].num_pages << endl; //Displays part of structure to make sure to works!!

        readBooks.getline(temp_paperback, 50, ',');
        //paperback = atoi(temp_paperback); //converts char to an int
        //bookArray[num_books].paperback = static_cast <bool> (paperback);
        //cout << bookArray[num_books].paperback << endl;*/

        num_books++;

        //ResizeArrays(bookArray, num_books);
        //}//End while

        readBooks.close();
    }//End if
    else
    {
        cout << "There was not an existing book file, so one will be created"  << endl;
    }//End else

    return 0;
}//End ReadBooks

void DisplayBooks(Book * bookArray, unsigned short num_books)
{
    for (unsigned short i = 0; i < num_books; i++)
    {
        cout << setw(30) << left << bookArray[i].title << left << setw(20) << bookArray[i].author_name << left << setw(15) << bookArray[i].isbn
             << left << setw(3) << bookArray[i].genre  << left<< setw(6) << bookArray[i].num_pages << left << setw(4) << bookArray[i].paperback << endl;
    }//End For
}//ENd Display Function

void ResizeArrays(Book * bookArray, unsigned short num_books)
{
    Book * temp_bookArray = new Book[num_books + 1];


    for (int i = 0; i < num_books; i++)
    {
        strcpy(temp_bookArray[i].title, bookArray[i].title);
        //cout << temp_bookArray[i].title << endl; //For Debugging

        strcpy(temp_bookArray[i].author_name, bookArray[i].author_name);
        //cout << temp_bookArray[i].author_name << endl; //for Debugging

        strcpy(temp_bookArray[i].isbn, bookArray[i].isbn);
        //cout << temp_bookArray[i].isbn << endl;//for debugging

        temp_bookArray[i].genre = bookArray[i].genre;
        //cout << temp_bookArray[i].genre << endl;//for debugging

        temp_bookArray[i].num_pages = bookArray[i].num_pages;
        //cout << temp_bookArray[i].num_pages << endl;// for debugging

        temp_bookArray[i].paperback = bookArray[i].paperback; 
        //cout << temp_bookArray[i].paperback << endl; //for debugging


    }//End for

    delete [] bookArray;

    bookArray = temp_bookArray; 

    DisplayBooks(bookArray, num_books); //debugging to make sure bookArray is reassigned


}//End Resize Function

strlen獲取所有不帶'\\ 0'的元素,因此如果您有str =“ 1234”; str的長度是5,(1234 +'\\ 0)但返回4.Strcpy取所有5個元素+'\\ 0'。

ResizeArrays存在問題:

  • 它為該數組分配新的內存,但不將該新數組返回給調用函數,因此它可以將其指針調整到新數組的位置。
  • 調整大小可能需要調整大小,舊大小和新大小,並且您將只能復制最少數量的元素。

只需將其修復到可以使用的程度,您可以執行以下操作:

Book* ResizeArrays(Book * bookArray, unsigned short num_books)
{ 
    ....
    return bookArray;
}

然后以這種方式使用該功能

bookArray = ResizeArrays(bookArray, num_books);

但是,在使用數組刪除時,對於第一次分配,還需要在main()中使用數組分配,

Book * bookArray = new Book[1];

即使只分配一本書,它也應該作為數組來完成,因此它與ResizeArrays中使用的delete []兼容。

我認為這是一項學習練習。 在C ++的正常使用中,您不會使用裸的new和delete運算符。 您可以簡單地使用std :: vector或類似方法,或者創建一個將管理內存的對象,並分別在構造函數和析構函數中使用new和delete。

我看到的問題:

問題1

沒有足夠的空間來正確容納ISBN。 輸入文件中ISBN的長度為14個字符。 要將它們保存在以空終止的字符串中,您需要一個可以容納15個或更多字符的數組。

結果,線

    readBooks.getline(temp_isbn, 14, ',');

由於必須使用第14個字符來存儲'\\0'因此它將停止讀取13個字符。

問題2

這條線看起來不正確。

    readBooks.getline(temp_numPages, 1000, ',');

我懷疑這是一個錯字,你的意思是

    readBooks.getline(temp_numPages, 50, ',');

問題3

ResizeArray的內存處理存在問題。

void ResizeArrays(Book * bookArray, unsigned short num_books)
{
    Book * temp_bookArray = new Book[num_books + 1];

    // Here, you are deleting the memory that was allocated in `main`.
    // bookArray in the calling function now points to memory that has been
    // deleted here.
    delete [] bookArray;

    // Here, you are changing the value of bookArray but only
    // locally in this function. This assignment doesn't
    // change the value of bookArray in the calling function.
    bookArray = temp_bookArray; 

    DisplayBooks(bookArray, num_books); //debugging to make sure bookArray is reassigned


}//End Resize Function

如果將ResizeArray更改為:

void ResizeArrays(Book*& bookArray, unsigned short num_books)

情況會更好。

問題4

我看到您已經注釋掉ReadBookswhile循環。 如果您決定使該循環恢復活力,則必須在每次循環中調整bookArray大小。

建議使用std::vector<Book*>來保存書籍,而不是為Books數組分配內存會更容易。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM