我知道我只是错过了一些愚蠢的东西,但我很沮丧,我只是看不到它。当我针对其中包含3个字段的文件运行以下代码“field1; field2; field3”时,任务将在retrieveTasks方法中正确打印出来。当该方法返回main时,输出已损坏。我知道这是愚蠢的,我只是想念它。我已经尝试将CourseName,TaskDescription等更改为数组而不是char *。我已经尝试将fileString作为char *传递,我已尝试使用strcpy而没有。有人能指出我的方向吗?
const int MAX_STRING_LENGTH = 101;
const int MAX_TASK_ITEMS = 255;
const char NEWLINE = '\n';
const char DELIMETER[] = ";";
const char FILENAME[] = "tasks.txt";
struct Task {
char* CourseName;
char* TaskDescription;
char* DueDate;
char FileString[300];
void printTask() {
cout << CourseName << DELIMETER << TaskDescription << DELIMETER << DueDate << endl;
}
void initializeFromFileString(char fileString[]) {
strcpy(FileString, fileString);
CourseName = strtok(FileString, DELIMETER);
TaskDescription = strtok(NULL, DELIMETER);
DueDate = strtok(NULL, DELIMETER);
}
};
struct TaskList {
Task Tasks[MAX_TASK_ITEMS];
int TaskCount;
void initialize() {
TaskCount = 0;
return;
}
void addTask(Task task) {
Tasks[TaskCount] = task;
TaskCount++;
return;
}
void printTasks() {
for(int TaskNum = 0; TaskNum < TaskCount; TaskNum++) {
cout << TaskNum + 1 << ". ";
Tasks[TaskNum].printTask();
cout << endl;
}
return;
}
// Load data from the file. Will return -1 if it fails for any reason.
// Otherwise it returns the number of records read.
int retrieveTasks(const char* fileName) {
int isSuccessfulOpen = 0;
int recordsRead = 0;
ifstream inFile;
isSuccessfulOpen = openFile(inFile, fileName);
if(!isSuccessfulOpen) {
return -1;
}
// Read input file and store in appropriate arrays
while(inFile.eof() == false) {
char fileLine[MAX_STRING_LENGTH * 3];
Task task;
inFile.getline(fileLine, MAX_STRING_LENGTH * 3, NEWLINE);
inFile.ignore(UINT_MAX, NEWLINE);
task.initializeFromFileString(fileLine);
addTask(task);
recordsRead++;
}
inFile.close();
return recordsRead;
}
};
int main() {
bool isFinished = false;
TaskList taskList;
taskList.initialize();
taskList.retrieveTasks(FILENAME);
taskList.printTasks();
return 0;
}
int openFile(ifstream& inFile, const char* fileName) {
inFile.open(fileName);
// Veryify that the file is valid. If not print error message.
if(inFile.is_open() == false) {
cout << "File " << fileName << " does not exist. Please provide a valid file path." << endl;
return 0;
}
return 1;
}
// Open file for writing
int openFile(ofstream& outFile, const char* fileName) {
outFile.open(fileName);
// Veryify that the file is valid. If not print error message and exit.
if(outFile.is_open() == false)
{
cout << "File " << fileName << " does not exist. Please provide a valid file path." << endl;
return 0;
}
return 1;
}
答案 0 :(得分:4)
CourseName
,TaskDescription
,DueDate
都指向task
循环内创建的while
对象中存在的数组中的内存。由于此task
对象是本地范围,因此在retrieveTasks
执行完毕后它们包含垃圾。
需要更改
您的TaskCount总是比计数多一个 - 因此需要减少1个。
for(int TaskNum = 0; TaskNum < TaskCount; TaskNum++) {
更改为
for(int TaskNum = 0; TaskNum < TaskCount -1 ; TaskNum++) {
从while循环中删除了Task对象。
AddTask
采用char *而不是Task。 AddTask
调用initializeFromFileString
,以便对数组的Task对象内的字符串执行strcpy
。此字符串也会调用strtok
更改
while(inFile.eof() == false) {
到
while(inFile) {
删除
inFile.ignore(UINT_MAX, NEWLINE);
固定代码
struct Task {
char* CourseName;
char* TaskDescription;
char* DueDate;
char FileString[300];
void printTask() {
cout << CourseName << DELIMETER << TaskDescription << DELIMETER << DueDate << endl;
}
void initializeFromFileString(char fileString[]) {
strcpy(FileString, fileString);
CourseName = strtok(FileString, DELIMETER);
TaskDescription = strtok(NULL, DELIMETER);
DueDate = strtok(NULL, DELIMETER);
}
};
int openFile(ifstream& inFile, const char* fileName) {
inFile.open(fileName);
// Veryify that the file is valid. If not print error message.
if(inFile.is_open() == false) {
cout << "File " << fileName << " does not exist. Please provide a valid file path." << endl;
return 0;
}
return 1;
}
// Open file for writing
int openFile(ofstream& outFile, const char* fileName) {
outFile.open(fileName);
// Veryify that the file is valid. If not print error message and exit.
if(outFile.is_open() == false)
{
cout << "File " << fileName << " does not exist. Please provide a valid file path." << endl;
return 0;
}
return 1;
}
struct TaskList {
Task Tasks[MAX_TASK_ITEMS];
int TaskCount;
void initialize() {
TaskCount = 0;
return;
}
void addTask(char * t) {
Tasks[TaskCount].initializeFromFileString(t);
TaskCount++;
return;
}
void printTasks() {
for(int TaskNum = 0; TaskNum < TaskCount - 1; TaskNum++) {
cout << TaskNum + 1 << ". ";
Tasks[TaskNum].printTask();
cout << endl;
}
return;
}
// Load data from the file. Will return -1 if it fails for any reason.
// Otherwise it returns the number of records read.
int retrieveTasks(const char* fileName) {
int isSuccessfulOpen = 0;
int recordsRead = 0;
ifstream inFile;
isSuccessfulOpen = openFile(inFile, fileName);
if(!isSuccessfulOpen) {
return -1;
}
// Read input file and store in appropriate arrays
while(inFile) {
char fileLine[MAX_STRING_LENGTH * 3];
inFile.getline(fileLine, MAX_STRING_LENGTH * 3, NEWLINE);
addTask(fileLine);
printTasks();
recordsRead++;
}
inFile.close();
return recordsRead;
}
};
很明显,如果你在C++
中编写它而不是在C inside classes
中编写它,整个程序会更简单,更不容易出错。