Ошибка подтверждения визуального strcpy Переполнение стека

Я студент. Просто изучаю 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

1

Решение

Есть проблемы с ResizeArrays:

  • Он выделяет новую память для массива, но не возвращает этот новый массив обратно вызывающей функции, чтобы он мог настроить свои указатели на новое местоположение массива.
  • Изменение размера, возможно, требует размеров, старого размера и нового размера, и вы сможете скопировать только минимальное количество элементов.

Просто чтобы исправить это до такой степени, что это сработает, вы можете сделать что-то вроде:

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

Затем используйте функцию таким образом

bookArray = ResizeArrays(bookArray, num_books);

Однако, так как вы используете удаление массива, для вашего первого выделения вам нужно использовать распределение массива и в main (),

Book * bookArray = new Book[1];

Несмотря на то, что он выделяет только одну книгу, он должен быть выполнен в виде массива, поэтому он совместим с delete [], используемым в ResizeArrays.

Я предполагаю, что это учебное упражнение. При обычном использовании C ++ вы бы не использовали голые операторы new и delete. Либо вы просто используете std :: vector или аналогичный, либо создаете объект, который будет управлять памятью, с new и delete в конструкторе и деструкторе соответственно.

-1

Другие решения

strlen получает все элементы без ‘\ 0’, поэтому, если у вас есть str = «1234»;
длина строки равна 5, (1234 + ‘\ 0), но возвращаемое значение 4.Strcpy принимает все 5 элементов +’ \ 0 ‘.

1

Проблемы, которые я вижу:

Проблема 1

Недостаточно места для правильного хранения ISBN. Длина ISBN во входном файле составляет 14 символов. Чтобы держать их в строке с нулевым символом в конце, вам нужно иметь массив, который может содержать 15 или более символов.

В результате линия

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

прекратит чтение после 13 символов, так как он должен использовать 14-й символ для хранения '\0',

Проблема 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

Я вижу, что вы закомментировали while зациклиться ReadBooks, Если вы решите вернуть этот цикл к жизни, вам придется изменить размер bookArray в каждом цикле цикла.

Предложение
Будет легче использовать std::vector<Book*> держать книги вместо того, чтобы выделять память для массивов Books,

-1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector