使用C++当我同时具有整数和字符数组时,如何将.txt文件中的数据作为链表的一部分访问
Using C++ how do I access data from a .txt file as part of a linked list when I have both integers and character arrays?
我的问题是我在.txt文件中有许多文件类型int以及长度为50的char数组。我有一个链表(队列结构)程序,它本质上是一个事件日历,具有用于搜索特定条目、星期几、日期和消息(有关事件的信息)的索引。无需从文件中读取,我可以创建事件、删除事件、修改事件、显示所有事件或显示单个事件。我需要补充的是:1.程序终止时保存所有事件的能力。2.然后下次打开它时,我需要能够从.txt文件中读取您的信息,并为.txt文件中的每个事件创建一个新事件。我的文本文件条目.txt显示在代码的正上方。每行如下:1.索引,2.星期几(星期日=1),3。日, 4.月, 5.年, 6.消息。在下面,它在一行上显示每个事件,但在我的.txt文件中,每个数字/字符都是一个新行。
142242015
Baseball_game_at_7231332015
This_event_is_for_nothing351762015生日
#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
#include <cmath>
using namespace std;
class Event{
protected:
int index;
enum DAY{Sunday=1, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};
int date[3];
char msg[50];
public:
Event *next;
Event *prev;
Event(){
next=NULL;
prev=NULL;
}
int a;
int day, day1;
virtual void getindex(int b){
index=b;
}
virtual int getindex2(){
a=index;
return a;
}
virtual void getindex3(int c){
index=c;
}
virtual void getday2(int d){
day=d;
}
virtual void getdate2(int e, int f, int g){
date[0]=e;
date[1]=f;
date[2]=g;
}
virtual void getmessage2(char h[50]){
msg=h;
}
virtual void getdate(){
cout<<"nOptions:n1. Sundayn2. Mondayn3. Tuesdayn4. Wednesdayn5. Thursdayn6. Fridayn7. SaturdaynWhich day would you like to select (enter the day): ";
cin>>day;
cout<<"Please enter the date you would like to use (In the form of dd mm yyyy): ";
cin>>date[0];
cin>>date[1];
cin>>date[2];
}
virtual void getcurrentdate(){
time_t now=time(0);
tm *local=localtime(&now);
time_t y=1900+local->tm_year;
time_t m=1+local->tm_mon;
time_t d=local->tm_mday;
time_t day1=local->tm_wday;
day=day1+1;
date[0]=d;
date[1]=m;
date[2]=y;
}
virtual void getmessage(){
cout<<"Please enter your message (Use _ for any spaces): ";
cin>>msg;
}
virtual void display(){
cout<<"nThe index is: "<<index<<endl;
switch(day){
case Sunday:
cout<<"The day of the week is: Sunday"<<endl;
break;
case Monday:
cout<<"The day of the week is: Monday"<<endl;
break;
case Tuesday:
cout<<"The day of the week is: Tuesday"<<endl;
break;
case Wednesday:
cout<<"The day of the week is: Wednesday"<<endl;
break;
case Thursday:
cout<<"The day of the week is: Thursday"<<endl;
break;
case Friday:
cout<<"The day of the week is: Friday"<<endl;
break;
case Saturday:
cout<<"The day of the week is: Saturday"<<endl;
break;
}
cout<<"The date is: "<<date[0]<<"/"<<date[1]<<"/"<<date[2]<<endl;
cout<<"The message is: "<<msg<<endl;
}
};
class Queue{
Event *Front, *Rear;
public:
Queue(){
Front=NULL;
Rear=NULL;
}
int index;
int input4;
void newevent(int x){
Event *temp;
temp=new Event;
if(Front==NULL){
Front=temp;
Rear=Front;
temp->prev=NULL;
}else{
Rear->next=temp;
temp->next=NULL;
temp->prev=Rear;
Rear=temp;
}
index=x;
temp->getindex(index);
cout<<"nOptions:n1. Enter a date manuallyn2. Use the current system date and timenWhat would you like to do: ";
cin>>input4;
switch(input4){
case 1: // Get date manually
temp->getdate();
break;
case 2: // Get current date
temp->getcurrentdate();
break;
}
temp->getmessage();
temp->display();
temp=NULL;
}
int p;
Event *temp2;
void deleteevent(){
Event *temp=Front;
Front=temp->next;
delete temp;
}
int c,d, input1, input3;
void modifyevent(int z){
d=z;
Event *temp=Front;
while(temp!=NULL){
for(c=1;c<d;c++){
temp=temp->next;
}
input1=0;
while(input1!=3){
cout<<"nOptions:n1. Change the daten2. Change the messagen3. exitnWhat would you like to update: ";
cin>>input1;
switch(input1){
case 1: // Change date
cout<<"Options:n1. Enter a date manuallyn2. Use the current system date and timenWhat would you like to do: ";
cin>>input3;
switch(input3){
case 1: // Get date manually
temp->getdate();
break;
case 2: // Get current date
temp->getcurrentdate();
break;
}
break;
case 2: // Change message
temp->getmessage();
break;
case 3: // Exit
break;
default:
cout<<"You entered an invalid number!";
}
}
temp=NULL;
}
}
int e,f;
void display(int z){
f=z;
Event *temp=Front;
while(temp!=NULL){
for(e=1;e<f;e++){
temp=temp->next;
}
temp->display();
temp->next;
temp=NULL;
}
}
void displayall(){
Event *temp=Front;
while(temp!=NULL){
temp->display();
cout<<"n";
temp=temp->next;
}
}
int end;
int x;
int y;
int a;
int b;
int g[3];
char h[50];
void readfromfile(){ // This was my attempt at the problem
ifstream fin;
fin.open("entries.txt");
Event *temp;
x=1;
y=1;
end=1;
while(fin>>y){
end++;
}
for(x;x<end;x++) { // till end-of-file
a=fin>>x;
x++;
b=fin>>x;
x++;
g[0]=fin>>x;
x++;
g[1]=fin>>x;
x++;
g[2]=fin>>x;
x++;
h=fin.getline(x);
temp=new Event;
if(Front==NULL){
Front=temp;
Rear=Front;
temp->prev=NULL;
}else{
Rear->next=temp;
temp->next=NULL;
temp->prev=Rear;
Rear=temp;
}
temp->getindex3(a);
temp->getday2(b);
temp->getdate2(g[0],g[1],g[2]);
temp->getmessage2(h);
temp=NULL;
}
fin.close();
}
void writetofile(){ //I understand this is blank, I havn't made it this far
}
};
int main(){
ofstream myfile;
myfile.open("entries.txt", ios::app);
cout<<"nWELCOME TO YOUR EVENT PLANNERn";
Queue a;
a.readfromfile();
int inp=0;
int i=0;
int num=4;
int type;
int counter=0;
int displayevent, modifyevent;
while(inp!=6){
cout<<"nOptions:n1. Create new eventn2. Delete the oldest eventn3. Modify an eventn4. Display all eventsn5. Display a specific eventn6. Exit event plannernWhat do you want to do: ";
cin>>inp;
switch(inp){
case 1: // New event
a.newevent(num);
num++;
counter++;
break;
case 2: // Delete event
a.deleteevent();
counter--;
break;
case 3: // Modify event
cout<<"nEnter the index of the event you would like to modify: ";
cin>>modifyevent;
a.modifyevent(modifyevent);
break;
case 4: // Display all events
a.displayall();
break;
case 5: //Display single event
cout<<"nEnter the index of the event you would like to display: ";
cin>>displayevent;
a.display(displayevent);
break;
case 6: // Exit event planner
break;
default:
cout<<"You entered an invalid number";
break;
}
}
cout<<"The current number of events is "<<counter<<endl;
myfile.close();
return 0;
}
Queue.readfromfile() 是我读取文件并将文件中的每个事件作为新事件输入的尝试。我需要知道如何将文本文件的每一行保存为不同的内容,以便将其发送到上面类中的函数。Queue.writetofile() 被故意留空,因为我甚至还没有做到那么远。我应该能够很容易弄清楚。我想先读完文件。
由于您没有搜索StackOverflow,因此我将为您提供有关如何输入内容的内容的概要。
让对象读取其数据成员。
有几种方法可以做到这一点,但我们将坚持重载提取运算符。
class Event
{
private:
int index;
int day_of_week;
unsigned int day;
unsigned int month;
unsigned int year;
std::string message; // Don't use char array here.
public:
friend std::istream& operator>>(std::istream& inp, Event& e);
};
std::istream&
operator>>(std::istream& inp, Event& e)
{
inp >> e.index;
inp >> e.day_of_week >> e.day >> e.month >> e.year;
std::getline(inp, e.message);
return inp;
}
要读取Event
代码片段,如下所示:
Event e;
my_input_file >> e;
读取和存储多个对象
您在许多Event
中读取的循环如下所示:
std::vector<Event> event_container;
Event single_event;
while (my_input_file >> single_event)
{
event_container.push_back(single_event);
}
事件链表
链表是一个容器,可以重用于不同的对象。
要创建事件的链接列表,您应该使用 std::list
:
std::list<Event> event_container;
Event single_event;
while (my_input_file >> single_event)
{
event_container.push_back(single_event);
}
链表类赋值
如果你碰巧因为类作业而需要编写链表,你应该将列表的实现与数据隔离开来:
struct Node
{
Node(Element * p_data = NULL)
: p_element(p_data), next(NULL)
{ ; }
Element * p_element;
Node * next;
};
struct Element_Linked_List
{
Node * p_head;
Node * p_tail;
Element_Linked_List()
: p_head(NULL), p_tail(NULL)
{ ; }
};
通过松散耦合容器中的数据(Element
),您将能够在即将到来的其他作业中使用此链表。
扩展封装 -- 日期类
我建议你更进一步,将一些工作负载和复杂性转移到Date
类中。
struct Date_DoW
{
static const char dow_names[] =
{
"Day Of Rest", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday", "Sunday",
}
enum Day_Of_Week {Monday = 1, Tuesday, Wednesday,
Thursday, Friday, Saturday, Sunday};
private:
void print_dow_name(Day_Of_Week dow, std::ostream& out)
{
out << dow_names(dow);
}
// etc...
};
你会把上面的课程增加几天、几个月和几年。
将日期重构为单独对象的一个优点是,您可以单独测试它,使其正常工作,而不必重新编译它。 您还可以在其他作业中重复使用它。
我会通过使用内置的 getline() 函数将文件的每一行转换为字符串,然后单独解析每个字符串来做到这一点。您可能还需要考虑在输入文件中使用分隔符来帮助解析过程。
编辑:这是我几个月前编写的程序的一个例子。该程序可以找到在一张或多张 LP 唱片上排列歌曲列表的所有可能方式。这是解析输入文件的程序部分:
vector<song> songs;
string input, title, min, sec, infile;
ifstream inputStream;
cout << endl << "Enter input file name:" << endl;
getline(cin, infile);
inputStream.open(infile, ios::in);
while (inputStream.good() && !inputStream.eof())
{
getline(inputStream, input);
input = regex_replace(input, regex("^\s+"), "");
input = regex_replace(input, regex("\s+"), " ");
if (input != "" && input[0]!='#') // # symbol can be used to comment out lines in the input file
{
title = input.substr(0, input.find_last_of(" "));
min = input.substr(title.length() + 1, input.find_last_of(":") - input.find_last_of(" ") - 1);
sec = input.substr(title.length() + min.length() + 2, input.length() - (title.length() + min.length() + 2));
songs.push_back(song(title, stoi(min), stoi(sec)));
}
}
inputStream.close();
对regex_replace的调用只是为了从数据中删除任何无意的空格填充(如果保证输入文件没有多余的填充,则无关紧要)。重要的部分是我使用 getline(inputStream, input) 一次一行地检索文件中的数据,然后使用 std::string 的 .substr() 函数来解析分隔符上的数据(如果您知道正在解析的数据的确切长度,则不需要)。
作为参考,以下是输入文件的格式设置方式:
Custard Pie 4:13
The Rover 5:37
In My Time of Dying 11:04
Houses of the Holy 4:02
Trampled Under Foot 5:37
Kashmir 8:32
In the Light 8:46
Bron-Yr-Aur 2:06
Down by the Seaside 5:13
Ten Years Gone 6:32
Night Flight 3:36
The Wanton Song 4:10
Boogie with Stu 3:53
Black Country Woman 4:24
Sick Again 4:42
- 如何将 txt 文件中的行分隔为组件C++
- 在CMakeLists.txt的安装功能中使用.cmake文件有什么用
- 一种在C++中读取TXT配置文件的简单方法
- 无法打开.txt文件
- 如何使用CLion在Mac上创建一个新的.txt文件
- 我可以读取静态对象中的文件.txt吗?C++
- C++-需要读取存储在文件(.txt)中的时间戳并正确检索
- 具有文件.txt的 C++ 中的设置
- 如何在 CMakeList 中包含 h/hpp 头文件.txt而不是 cpp 或其他 hpp 文件
- 使用函数读取文件.txt中的矩阵
- 任何人都知道如何解决尝试将从MySQL数据库返回的行打印到文本文件(.txt)中的C++
- 读取文件.txt C
- 为什么我的方法不从文件.txt中读取float类型
- 如何读取名称(仅文件.txt)作为参数传递的文件(在任何目录中)?C++
- 读取文件".txt"并将每行的数据分配给循环列表中的新节点C++
- 如何用C++将字符串文件Txt解析成数组
- 如何在c++中读取和编辑文件txt
- 从文件.txt读取字符串数组并使用它来玩康威的生命游戏
- 导入文件txt时出错
- 如何仅读取文件.txt中的数字