为什么我得到"访问违规错误阅读"在以下计划中:
错误在while循环上读取文件。
#include <iostream>
class fileReader
{
public:
FILE *fp;
char** lines;
fileReader()
{
fp = NULL;
}
fileReader(const char* path)
{
int i=0;
fp = fopen(path,"r");
while ( fgets(lines[i], 100, fp) )
i++;
}
};
int main(int argv, char** argc)
{
const char* path = "D:\\PS4263-2.txt";
fileReader *p = new fileReader(path);
for (int i=0; i<2; i++)
std::cout<<p->lines[i];
return 0;
}
正如答案中提到的,我将代码更改为(下方),但我仍然遇到同样的错误。
#include <iostream>
class fileReader
{
public:
FILE *fp;
char** lines;
fileReader()
{
fp = NULL;
}
fileReader(char* path)
{
int j=0;
fp = fopen(path,"r");
if (fp == NULL)
return;
else
{
lines = (char**) malloc(sizeof(char *)*56000);
for (int i=0; i<56000; i++)
lines[i] = (char*)malloc(sizeof(char)*1440);
while ( fgets(lines[j], 1440, fp) )
j++;
fclose(fp);
}
}
};
int main(int argv, char** argc)
{
char* path = "D:\\testfile.txt";
fileReader *p = new fileReader(path);
for (int i=0; i<2; i++)
std::cout<<p->lines[i];
return 0;
}
答案 0 :(得分:1)
char** lines;
从未分配任何记忆!
为了能够用它做任何有意义的事情,你需要分配足够的内存来保存你想要保存在其中的内容。
另见旁注,
p
来释放分配给delete p;
的动态内存,这会给您一个未定义的行为。答案 1 :(得分:1)
您的代码中存在许多问题:
char** lines
尚未分配。您需要分配lines
和
lines[i]
。fp
。fclose(fp)
。编辑:
您尚未取消分配lines
,lines[i]
和p
。请注意,您必须free()
使用lines
,lines[i]
使用delete
和p
。
答案 2 :(得分:1)
此代码存在许多问题。但主要是,问题是你正在写一些邪恶的C / C ++混合。选择两种语言中的一种,并使用它。
以下是您的代码的修订版本:
#include <iostream>
class fileReader
{
public:
FILE *fp;
char** lines;
fileReader() : fp(NULL) // initialization of members happens here
{
//fp = NULL; // anything here happens *after* initialization
lines = new char*[100]; // let's just assume max 100 lines. We have to allocate space for them
for (int i = 0; i < 100; ++i) {
lines[i] = new char[100]; // allocate space for the contents of each individual line
}
}
fileReader(const char* path)
{
lines = new char*[100]; // let's just assume max 100 lines. We have to allocate space for them
for (int i = 0; i < 100; ++i) {
lines[i] = new char[100]; // allocate space for the contents of each individual line
}
int i=0;
fp = fopen(path,"r");
while ( fgets(lines[i], 100, fp) )
i++;
}
~fileReader() {
// deallocate and close our members:
fclose(fp);
for (int i = 0; i < 100; ++i) {
delete[] lines[i]; // delete the contents of each line
}
delete[] lines; // delete the lines array
}
};
int main(int argv, char** argc)
{
const char* path = "D:\\PS4263-2.txt";
fileReader p(path); // don't use new unless you really really have to
for (int i=0; i<2; i++)
std::cout<<p.lines[i];
return 0;
}
现在至少它可以工作,如果每行包含少于100个字符和 少于100行和该文件存在且我们真正应该防范的十几个其他条件。特别是,我们在内存管理方面投入了大量精力:为所有行数据分配和释放空间。
但是,如果我们真正开始编写C ++,我们可以通过一些更改来做得更好。
#include <iostream> // we need this for the standard streams (cout)
#include <fstream> // we need proper C++ file streams too
#include <string> // C++ has strings. Don't waste your time on char pointers
#include <vector> // C++ has a dynamic array class. Don't use pointers as ad-hoc arrays
class fileReader
{
public:
// FILE* fp; // no point in making this a class member, when it's only used in one function
std::vector<std::string> lines; // use a vector of strings. Much easier to manage
fileReader() // vectors are automatically initialized, no need to do anything
{
}
fileReader(std::string path)
{
std::ifstream fp(path); // create an input file stream
std::string result; // store the contents of the current line here
while (std::getline(fp, result)) {
lines.push_back(result); // append the resulting line to the end of the vector
}
}
};
int main(int argv, char** argc)
{
std::string path = "blah.txt";
fileReader p(path); // don't use new unless you absolutely have to
for (int i=0; i<2; i++)
std::cout<<p.lines[i];
return 0;
}
请注意,我们不再需要管理数组内存。当矢量和字符串超出范围时,它们会自动清理。由于我们不再使用new
来分配fileReader
,因此当 超出范围时,它会自动被删除。这有效地启动了一个连锁反应,其成员自己开始清理:文件流关闭,向量在询问其存储的字符串清理和关闭后释放其内存。并且整个程序折叠并关闭,而我们不必编写一行代码来处理它。