我正在做一个菜单驱动的程序,让用户基本上跟踪他们的分配任务和截止日期。我的程序处理一个名为"tasks.txt"的文本文件,用户有3个与文本文件交互的选项:输入一个新任务,显示文件中的所有任务,或按课程查找任务。我的程序运行得比较好,除了它似乎不能完全与文件交互。
下面是我的输出/输入文件:tasks.txtCS162;Finish Project 2;04/10/2015
CS162;Finish Project 3;04/20/2015
CS162;Finish Project 4;05/10/2015
CS162;Finish Project 5;05/20/2015
下面是我的代码:
#define _CRT_SECURE_NO_WARNINGS
#include <cstring>
#include <fstream>
#include <iostream>
using namespace std;
//Global constants
const int CAP = 100;
const int MAXCHAR = 201; // Task description can be a max of 200 characters in case its a long description (ie: specific instructions)
//Task struct
struct Task
{
char courseName[MAXCHAR];
char taskDescrip[MAXCHAR];
char dueDate[MAXCHAR];
};
//function prototypes
void openFile(ifstream &inFile);
void loadData(ifstream &inFile, Task tasks[], int &listSize);
void exeCommand(char option, Task tasks[], int &listSize);
void displayMenu();
char readOption();
void getUserTask(Task &tempTask);
void addUserTask(Task tasks[], int &listSize, Task tempTask);
void printTasks(Task tasks[], const int listSize);
void writeFile(ofstream &outFile, Task tasks[], const int listSize);
//Main function
int main()
{
int listSize = 0; //keep track of list size
ofstream outFile; //output file stream variable
ifstream inFile; //input file stream variable
Task tasks[CAP]; //array of tasks
char option; // user menu input for option
openFile(inFile); //open up tasks.txt
loadData(inFile, tasks, listSize); //load the data while in file into the array of tasks
do
{
displayMenu();
option = readOption();
exeCommand(option, tasks, listSize);
} while (tolower(option) != 'q');
return 0;
}
//open the file
void openFile(ifstream &inFile)
{
inFile.open("tasks.txt");
if (!inFile)
{
cout << "file not open" << endl;
exit(0);
}
}
//load the data from the file to the array
// parameters:
void loadData(ifstream &inFile, Task tasks[], int &listSize)
{
while (!inFile.eof())
{
inFile.get(tasks[listSize].courseName, MAXCHAR, ';');
inFile.ignore(200, ';');
inFile.get(tasks[listSize].taskDescrip, MAXCHAR, ';');
inFile.ignore(200, ';');
inFile.get(tasks[listSize].dueDate, MAXCHAR, ';');
inFile.ignore(200, 'n');
listSize++;
}
inFile.close();
}
void displayMenu()
{
cout << "Welcome to TaskTracker v.1" << endl;
cout << "(a) Add a task" << endl;
cout << "(l) List all tasks" << endl;
cout << "(f) Find any tasks by course" << endl;
cout << "(q) Quit" << endl << endl;
}
char readOption()
{
char option;
cout << "Please make a selection: ";
cin.get(option);
cin.ignore(100, 'n');
return option;
}
void exeCommand(char option, Task tasks[], int &listSize)
{
Task tempTask;// created object tempTask
switch (tolower(option))
{
case 'a':
cout << "You chose to add a task!" << endl;
getUserTask(tempTask);//used aVideo as a parameter for getVideo
addUserTask(tasks, listSize, tempTask);//tempTask
cout << endl << endl;
break;
case 'l':
cout << "You chose print tasks!" << endl;
printTasks(tasks, listSize);
cout << endl << endl;
break;
case 'f':
cout << "You chose to find an item by course!"<< endl;
cout << endl << endl;
break;
case 'q':
return;
default:
cout << "Invalid input!" << endl;
}
}
void getUserTask(Task &tempTask)
{
cout << "Please enter the course name {less than 101 characters): ";
cin.get(tempTask.courseName, MAXCHAR);//user enters the course name
cin.ignore(100, 'n');//ignores the next 100 characters or until newline
cout << "Please enter a brief description of your task (less than 101 characters): ";
cin.get(tempTask.taskDescrip, MAXCHAR);//user enters the task description
cin.ignore(100, 'n');//ignores the next 100 characters or until newline
cout << "Please enter the due date of this task. (mm/dd/yyy): ";
cin.get(tempTask.dueDate, MAXCHAR);//user enters the task description
cin.ignore(100, 'n');
}
void addUserTask(Task tasks[], int &listSize, Task tempTask)
{
tasks[listSize++] = tempTask;
}
//prints the task list
void printTasks(Task tasks[], const int listSize)
{
for (int i = 0; i < listSize; i++)
{
cout << tasks[i].courseName << ';' << tasks[i].taskDescrip << ';' << tasks[i].dueDate << endl;
}
}
//writes to file at the end of the program
void writeFile(ofstream &outFile, Task tasks[], const int listSize)
{
outFile.open("tasks.txt");
for (int i = 0; i < listSize; i++)
{
outFile << tasks[i].courseName << ';' << tasks[i].taskDescrip << ';' << tasks[i].dueDate << endl;
}
return;
}
调试器的输出如下:
Welcome to TaskTracker v.1
(a) Add a task
(l) List all tasks
(f) Find any tasks by course
(q) Quit
Please make a selection: l
You chose print tasks!
CS162;Finish Project 2;04/10/2015
CS162
CS162;Finish Project4;05/10/2015
CS162
Welcome to TaskTracker v.1
(a) Add a task
(l) List all tasks
(f) Find any tasks by course
(q) Quit
我已经对代码进行了几个小时的剥离,并在网上搜索类似的案例,但似乎我的fstream能够读取和加载每一行的课程名称,但跳过任务描述和其他任务的截止日期。有人能给我指个正确的方向吗?
菜单的Add选项似乎可以将新的用户输入任务加载到缓冲区中,但是应该将缓冲区中的所有任务保存到输出文件的writefile函数似乎也不起作用。
我将继续寻找解决方案,但任何帮助是非常感谢!输入处理出错。我的建议是:
void loadData(ifstream &inFile, Task tasks[], int &listSize)
{
while (inFile.get(tasks[listSize].courseName, MAXCHAR, ';') &&
inFile.ignore(200, ';') &&
inFile.get(tasks[listSize].taskDescrip, MAXCHAR, ';') &&
inFile.ignore(200, ';') &&
inFile.get(tasks[listSize].dueDate, MAXCHAR, 'n'))
{
inFile.ignore(200, 'n');
listSize++;
}
inFile.close();
}
产生以下输出:
Welcome to TaskTracker v.1
(a) Add a task
(l) List all tasks
(f) Find any tasks by course
(q) Quit
Please make a selection: l
You chose print tasks!
CS162;Finish Project 2;04/10/2015
CS162;Finish Project 3;04/20/2015
CS162;Finish Project 4;05/10/2015
CS162;Finish Project 5;05/20/2015
简而言之,您对第三个字段的请求也以';'
结束(它在您的示例行中而不是这样做)将跳到下一行,直到它找到所请求的分隔符,从而包括中间换行符和下一行的第一个字段。当前行的剩余部分与后续的ignore
一起被丢弃。
祝你好运。