简体   繁体   English

C ++从文本文件中读取字符串,并将每个单词保存到链表中

[英]C++ Read String from Text file and save word by word into linkedlist

I am assigned to write a c++ program for room booking system. 我被分配编写一个用于房间预订系统的C ++程序。 I know how to read a text file line by line and save it. 我知道如何逐行读取文本文件并将其保存。 but my problem is how to read text file word by word. 但是我的问题是如何逐字读取文本文件。

This is the text file I have: 这是我拥有的文本文件:

1-Reserved-2018-12-23-Lecture Room-13
2-Reserved-2018-11-34-Tutorial Room-15
3-Not Reserved-0-0-0-Design Studio-18
4-Reserved-2018-11-16-Lecture Room-14
5-Not Reserved-0-0-0-Exam Hall-18

I want to read the text file and save the words into it nodes. 我想读取文本文件并将单词保存到节点中。 (Like ID , data , typeofRoom , etc.) Is there any way to do so in C++? (例如IDdatatypeofRoom等。)在C ++中有什么方法可以这样做?

This is my class: 这是我的课:

class room {

public:

    int length;
    int initial;

    enum class roomType { main_hall, exam_hall, lecture_room, tutorial_room, design_studio, meeting_room };
    struct node {

        string data;
        int id;
        int capacity;
        int year, month, day;
        int deleteDate;
        roomType type;
        node* next;
    };
    node* front;
    node * tail;
    room() {
        length=0;
        initial=1;

        front = NULL;
        tail = NULL;
    }

    bool isFull () { return length>=20; }


    // Add Rooms
    void room::addRoom() {
        system("cls");

   if (isFull()) {

       cout<<"    No more than 25 rooms are allowed\n"<<endl;
       return;
   }

        cout << "Enter the capacity" << endl;
        int a;
        cin >> a;

        node* temp = new node();
        temp->data = "Not Reserved";
        temp->id = initial;
        temp->year = 0;
        temp->month = 0;
        temp->day = 0;
        temp->deleteDate = 0;

        initial++;
        temp->capacity = a;
        temp->next = NULL;
        if (front == NULL && tail == NULL)
        {
            front = temp;
            tail = temp;
        }
        else {
            tail->next = temp;
            tail = temp;
        }
        cout << "Choose The type" << endl;
        cout << "1- Main Hall \t 2- Lecture Room \t 3- Exam Hall \t 4- Meeting Room \t 5- Design Studio \t 6- Tutorial Room" << endl;
        int t;
        cin >> t;
        if (t == 1)
        {
            temp->type = roomType::main_hall;

        }
        else if (t == 2)
        {
            temp->type = roomType::lecture_room;

        }
        else if (t == 3)
        {
            temp->type = roomType::exam_hall;


        }
        else if (t == 4)
        {
            temp->type = roomType::meeting_room;


        }
        else if (t == 5)
        {
            temp->type = roomType::design_studio;


        }
        else if (t == 6)
        {
            temp->type = roomType::tutorial_room;


        }
        else {cout << "Wrong Input!" << endl;}
        length++;
        cout<<"\n Successfully Created!\n\n";
        system("pause");
        save();
    }
    void reserveRoom()
    {
        system("cls");
        show();
        cout << "=============================================================" << endl;
        cout << "Enter the room ID you want to Book !" << endl;
        int id;
        cin >> id;
        node* tmp = front;

        while (tmp != NULL) {
            if (tmp->id == id) {
                if(tmp->data == "Not Reserved"){
                tmp->data = "Reserved";
                int y,m,d;

                cout << "Enter the year " << endl;
                cin >> y;

                cout << "Enter the month " << endl;
                cin >> m;

                cout << "Enter the day " << endl;
                cin >> d;

                tmp->year = y;
                tmp->month = m;
                tmp->day = d;
                tmp->deleteDate = y+m+d;


                cout << "Room Reserved!" << endl;
                }
                else{
                    cout << "This room has been reserved!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;

                }
            }
            tmp = tmp->next;
        }
        system("pause");
        room::save();

    }
};

I know how to read a text file line by line and save it. 我知道如何逐行读取文本文件并将其保存。 but my problem is how to read text file word by word. 但是我的问题是如何逐字读取文本文件。

This is the text file I have: 这是我拥有的文本文件:

 1-Reserved-2018-12-23-Lecture Room-13 2-Reserved-2018-11-34-Tutorial Room-15 3-Not Reserved-0-0-0-Design Studio-18 4-Reserved-2018-11-16-Lecture Room-14 5-Not Reserved-0-0-0-Exam Hall-18 

Continuing from my comment above, whenever you are faced with separating words in a line with a delimiter in between the words, a standard approach is the each line into a string with getline and then create a stringstream from the line reading each word into a string using getline with the delimiter specified. 继续我上面的评论,每当您遇到将单词分隔成一行并在单词之间使用分隔符的情况时,一种标准的方法是将每一行都用getline组成一个string ,然后从该行创建一个stringstream ,将每个单词读为一个stringgetline与指定的分隔符一起使用。

Why Read a Line with getline and Read a stringstream with getline Again? 为什么要阅读与线getline和阅读stringstreamgetline一遍吗?

Answer: line-control. 答:线路控制。

While you could simply read directly from your file using getline and a delimiter, which would separate each word, how would you know when one line ended and the next line began? 虽然您可以简单地使用getline和分隔符直接读取文件,分隔符将每个单词分开,但是您如何知道一行结束和下一行开始的时间呢? When you specify the delimiter to use with getline , getline will read until the delimiter is found or end of input or str.max_size characters have been read. 当您指定与getline一起使用的定界符时, getline会一直读取,直到找到定界符或已读完输入或str.max_size字符str.max_size See cppreference.com - std::getline . 参见cppreference.com-std :: getline So there is no special meaning to the line-ending '\\n' in this case. 因此,在这种情况下,行尾'\\n'没有特殊含义。

However, if you read the entire line into a string and then create a stringstream from the line, you know you can only read until the end-of-line as that will trigger the end-of-file condition on input. 但是,如果你读了整条生产线成string ,然后创建一个stringstream从行,你知道你只能读,直到最后的行为,将触发输入端的文件状态。 So even though you are using getline with a delimiter, it can now only read as far as the end of line. 因此,即使您使用带有分隔符的getline ,它现在也只能读取到行尾。

A short example using this approach and using your data file will show how you can separate each line into words that you can then add to each node of your list, eg 一个使用此方法并使用数据文件的简短示例将说明如何将每一行分成单词,然后将其添加到列表的每个节点,例如

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

int main (int argc, char **argv) {

    std::string line;   /* string to hold each line */

    if (argc < 2) {     /* validate at least 1 argument given */
        std::cerr << "error: insufficient input.\n"
                "usage: " << argv[0] << " filename\n";
        return 1;
    }

    std::ifstream f (argv[1]);  /* open file */
    if (!f.is_open()) {         /* validate file open for reading */
        perror (("error opening file " + std::string(argv[1])).c_str());
        return 1;
    }

    while (getline (f, line)) {         /* read each line into line */
        std::string word;               /* string to hold words */
        std::stringstream s (line);     /* create stringstream from line */
        while (getline (s, word, '-'))  /* read hyphen separated words */
            std::cout << word << '\n';  /* output words */
        std::cout << '\n';  /* tidy up with newline between data */
    }
}

Example Input File 输入文件示例

$ cat ../dat/hyphenstr.txt
1-Reserved-2018-12-23-Lecture Room-13
2-Reserved-2018-11-34-Tutorial Room-15
3-Not Reserved-0-0-0-Design Studio-18
4-Reserved-2018-11-16-Lecture Room-14
5-Not Reserved-0-0-0-Exam Hall-18

Example Use/Output 使用/输出示例

Note, the code above simply outputs an additional '\\n' between the words separated from each line. 注意,上面的代码只是在与每行分隔的单词之间简单地输出一个附加的'\\n' You would write logic (perhaps using a counter, and, eg stoi for any needed conversions) to convert the values to integer values and store each in its proper field. 您将编写逻辑(也许使用计数器,例如,进行任何需要的转换为stoi )以将值转换为整数值并将每个值存储在其适当的字段中。

$ ./bin/getline_hyphen ../dat/hyphenstr.txt
1
Reserved
2018
12
23
Lecture Room
13

2
Reserved
2018
11
34
Tutorial Room
15

3
Not Reserved
0
0
0
Design Studio
18

4
Reserved
2018
11
16
Lecture Room
14

5
Not Reserved
0
0
0
Exam Hall
18

You can also remove the separators from each line, create a separate stringstream without the hyphens and use >> to read and convert the values for each node. 您还可以从每一行中删除分隔符,创建一个不带连字符的单独stringstream ,并使用>>读取和转换每个节点的值。 (this second approach is left to you) (第二种方法留给您)

Look things over and let me know if you have further questions. 仔细检查一下,如果您还有其他问题,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM