如何从 .txt 中提取文本并将其存储到动态二维数组中?
How to pull text out of a .txt and store it into a dynamic 2d array?
我需要从我的 .txt 文件中逐行提取文本并将其存储到动态数组中,每次从 .txt 文件中提取新行时都会分配新的 space。我的代码似乎很好地提取了第一行并将其存储到第一个指针数组中,但在第二个循环中,它似乎重置了所有指针数组,这在我稍后尝试访问它时给我内存分配错误。为什么会发生这种情况,尤其是当我在将内容存储到指针及其数组后不触摸它们时?
char** temp = nullptr;
char buffer[256];
int index = 0;
// Open File
fstream myFile;
myFile.open("pantry.txt", ios::in);
if (myFile.is_open())
{
while (!myFile.eof())
{
myFile >> buffer; // Pull line out of txt.file
temp = new char* [index + 1]; // Create new pointer
temp[index] = new char[strlen(buffer)+1]; // Create char array pointed at by new pointer
#pragma warning(suppress : 4996) // Turns off complier warning
strcpy(temp[index], buffer); //Copy buffer into new char array
index++; // Increment our index counter int
}
for (int i = 0; i < index; i++)
{
cout << temp[i] << endl;
}
如果分配和存储正确,我希望它能够准确地打印出 txt 文件。
相反,我得到
Exception thrown at 0x7B9A08CC (ucrtbased.dll) in PE 12.4.exe: 0xC0000005: Access violation reading location 0xCDCDCDCD.
pantry.txt
Basil
Flat Leaf Parsely
Thyme
Sage
Cumin
Steak Seasoning
Mace
Garlic Powder
显示的代码中存在多个错误。
while (!myFile.eof())
这是 always a bug 也必须修复,除了显示代码的主要问题:
temp = new char* [index + 1];
为了帮助您理解这一行的问题,记住计算机编程的黄金法则会很有帮助:
Your computer always does exactly what you tell it to do instead of
what you want it to do.
根据黄金法则,以上行准确地告诉您的计算机:“new
某物,并将其分配给 temp
”。
这就是您的计算机每次执行此行时将执行的操作。此行在该循环的每次迭代中执行一次。下次这个循环运行时,之前 new
ed temp
将被另一个替换,泄漏它之前指向的所有内容。为什么你的计算机要在这条线上做任何其他事情?毕竟,这正是您告诉计算机要做的。这就是为什么您观察到这将在循环的每次迭代中“重置所有指针数组”,从而导致“内存分配错误”。
无论如何,这整块逻辑都需要从头开始废弃和重写,这次要使用正确的逻辑。最简单的做法是实际使用 C++ 库的 std::vector
和 std::string
对象,它们将为您正确分配所有内存。现代 C++ 代码很少需要 new
任何东西,而是使用 C++ 库的容器。
您的作业目标可能是演示正确使用低级内存分配和释放逻辑。在这种情况下,您将需要找到一些其他方法来执行此操作。由于您事先不知道行数,因此一种方法是构建一个链表,每次一行,因为每一行都从文件中读取。只有在读取整个文件(并且行数已知)、指针移动到数组并删除临时链表后,才会分配最终数组和所有字符指针。或者,也许实现一个类似于 std::vector
的算法,逐步分配一个新的指针数组,当它已满时,将所有字符指针复制到一个更大的数组,然后删除原始数组。
当然,工作量很大。但是,除非你的分配或任务的目的是正确地实现低级内存分配和释放,否则为什么要经历所有的工作和痛苦来做 std::vector
和 std::string
已经做的事情,当你可以简单地使用它们,只需五六行代码,就能取代以上所有内容?
我需要从我的 .txt 文件中逐行提取文本并将其存储到动态数组中,每次从 .txt 文件中提取新行时都会分配新的 space。我的代码似乎很好地提取了第一行并将其存储到第一个指针数组中,但在第二个循环中,它似乎重置了所有指针数组,这在我稍后尝试访问它时给我内存分配错误。为什么会发生这种情况,尤其是当我在将内容存储到指针及其数组后不触摸它们时?
char** temp = nullptr;
char buffer[256];
int index = 0;
// Open File
fstream myFile;
myFile.open("pantry.txt", ios::in);
if (myFile.is_open())
{
while (!myFile.eof())
{
myFile >> buffer; // Pull line out of txt.file
temp = new char* [index + 1]; // Create new pointer
temp[index] = new char[strlen(buffer)+1]; // Create char array pointed at by new pointer
#pragma warning(suppress : 4996) // Turns off complier warning
strcpy(temp[index], buffer); //Copy buffer into new char array
index++; // Increment our index counter int
}
for (int i = 0; i < index; i++)
{
cout << temp[i] << endl;
}
如果分配和存储正确,我希望它能够准确地打印出 txt 文件。 相反,我得到
Exception thrown at 0x7B9A08CC (ucrtbased.dll) in PE 12.4.exe: 0xC0000005: Access violation reading location 0xCDCDCDCD.
pantry.txt
Basil
Flat Leaf Parsely
Thyme
Sage
Cumin
Steak Seasoning
Mace
Garlic Powder
显示的代码中存在多个错误。
while (!myFile.eof())
这是 always a bug 也必须修复,除了显示代码的主要问题:
temp = new char* [index + 1];
为了帮助您理解这一行的问题,记住计算机编程的黄金法则会很有帮助:
Your computer always does exactly what you tell it to do instead of what you want it to do.
根据黄金法则,以上行准确地告诉您的计算机:“new
某物,并将其分配给 temp
”。
这就是您的计算机每次执行此行时将执行的操作。此行在该循环的每次迭代中执行一次。下次这个循环运行时,之前 new
ed temp
将被另一个替换,泄漏它之前指向的所有内容。为什么你的计算机要在这条线上做任何其他事情?毕竟,这正是您告诉计算机要做的。这就是为什么您观察到这将在循环的每次迭代中“重置所有指针数组”,从而导致“内存分配错误”。
无论如何,这整块逻辑都需要从头开始废弃和重写,这次要使用正确的逻辑。最简单的做法是实际使用 C++ 库的 std::vector
和 std::string
对象,它们将为您正确分配所有内存。现代 C++ 代码很少需要 new
任何东西,而是使用 C++ 库的容器。
您的作业目标可能是演示正确使用低级内存分配和释放逻辑。在这种情况下,您将需要找到一些其他方法来执行此操作。由于您事先不知道行数,因此一种方法是构建一个链表,每次一行,因为每一行都从文件中读取。只有在读取整个文件(并且行数已知)、指针移动到数组并删除临时链表后,才会分配最终数组和所有字符指针。或者,也许实现一个类似于 std::vector
的算法,逐步分配一个新的指针数组,当它已满时,将所有字符指针复制到一个更大的数组,然后删除原始数组。
当然,工作量很大。但是,除非你的分配或任务的目的是正确地实现低级内存分配和释放,否则为什么要经历所有的工作和痛苦来做 std::vector
和 std::string
已经做的事情,当你可以简单地使用它们,只需五六行代码,就能取代以上所有内容?