【问题标题】:What format should I write my .txt file if I want to getline for C++ program?如果我想为 C++ 程序获取 getline,我应该编写什么格式的 .txt 文件?
【发布时间】:2020-07-27 07:28:08
【问题描述】:

我的主程序中有这段代码。 我不知道我的文本文件应该格式化成什么方式让我的主getline从中获取。

//...
BOOK_TYPE book[100];
int index = -1, choice;

input.getline(book[++index].isbn, 14);

while (input)
{
    input.getline(book[index].author, 20);
    input.getline(book[index].title, 30);
    input.getline(book[index].publisher, 20);
    input.getline(book[index].year, 5);
    input.getline(book[index].price, 10);
    input.getline(book[index].quantity, 103);

    for (int k = 0; k < 5; k++)
    {
        input.getline(book[index].category[k].cor_x, 2);
        input.getline(book[index].category[k].cor_y, 2);
        input.getline(book[index].category[k].genre, 20);
    }
    // clear unwanted whitespace
    if (input.peek() == '\n')
        input.ignore(256, '\n');
    // read next number
    input.getline(book[++index].isbn, 14);
}
input.close();
//...

假设我有这个书单:

9780809875214,John Wick,The assasinate of a Gang,Tree Production,2014,39.00,4,2,2
9788373191723,J.R.R Tolkien,The Lord of the Rings,Allen & Unwin,1954,120.45,6,3,1
9783791535661,Lewis Carroll, Alice's Adventure in Wonderland,Macmillan Publishers,1865,100.25,5,3,2
9781517322977,Mikhail Bulgakov,The Master and Margartia,Penguin Books,1967,125.00,7,3,3
9780676516197,Vladmir Nabokov,Lolita,Olympia Press,1955,98.25,3,3,1
9781095627242,Anna Sewell,Black Beauty,The Jarrold Group,1877,60.25,2,3,2
9788497592581,Umberto Eco,The Name of the Rose,Bompiani,1980,45.65,7,1,3
9780062316110,Harari and Yuval Noah,Sapiens: A Brief History of Humankind,Harper Perennial,2018,18.06,2,1,3

我想知道应该在哪里间隔,输入下一行等等,以便我的文件可以逐行读取,并在用户选择时作为书单输出给用户。

【问题讨论】:

  • 您拥有的是一个Comma-Separated Values (or CSV) 文件。您可以使用std::getline 首先将整行读入一个字符串,然后再次对其进行标记。 (也可以使用istream::getline 完成,但请不要使用它)。或者你可以找到一个为你做这件事的图书馆(这真的是我推荐的,除非它是作业的一部分)。重要的部分是不要忘记 分隔符
  • @Someprogrammerdude 我在一个结构文件中有不同的数组,如果我把整行变成一个字符串,它如何被分成不同的数组?

标签: c++ fstream getline


【解决方案1】:

您可以使用std::getlinestd::stringstream阅读所有书籍。

请注意,您缺少文件中的流派属性。

这是一个带有 cmets 的示例程序,我从你的代码中推断出类,如果有什么不准确的,你可以重构代码:

Running sample

#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>

class Category {
public:
    int cor_x;
    int cor_y;
    std::string genre;
};

class BOOK_TYPE {
public:
    std::string isbn;
    std::string author;
    std::string title;
    std::string publisher;
    std::string year;
    double price;
    int quantity;
    Category category;
};

int main() {

    std::vector<BOOK_TYPE> books; //dynamic container for books

    BOOK_TYPE book;
    std::string temp, price, quantity, cor_x, cor_y, genre, tempin;
    std::fstream input;
    input.open("test.txt");

    if(!input.is_open()){
        std::cerr << "No file";
        return 1;
    }      

    while (std::getline(input, tempin)) //read each whole line till there are no more
    {
        std::stringstream temp(tempin); //stream format
        getline(temp, book.isbn, ','); //read all properties with commma separator
        getline(temp, book.author, ',');
        getline(temp, book.title, ',');
        getline(temp, book.publisher, ',');
        getline(temp, book.year, ',');
        getline(temp, price, ',');
        book.price = stod(price);
        getline(temp, quantity, ',');
        book.quantity = stoi(quantity);
        getline(temp, cor_x, ',');
        book.category.cor_x = stoi(cor_x);
        getline(temp, cor_y, ',');
        book.category.cor_y = stoi(cor_y);        
        getline(temp, book.category.genre);
        books.push_back(book);  //add book to the vector of books
    }
    input.close();

    //test print some of the properties in range based loop, you can print the rest
    // you can use the normal for loop with books[i] and i < books.size()
    for(auto book : books)
        std::cout << book.title << " " << book.author <<  " " << book.isbn << " " 
        << book.category.cor_y << " " << book.category.cor_x << " " 
        << book.price << " " <<  book.category.genre << std::endl;
}

【讨论】:

  • 我可以知道我们为什么要使用 stoi 和 stod 吗?
  • @brightnow, std::getline 不能直接从流中读取到intdouble,必须先读取到std::string 然后再转换,std::stoi 到 int 和和std::stod 加倍。如果您觉得它解决了您的问题,请不要忘记accept the answer
  • @brightnow,不客气,我很高兴能帮上忙。
【解决方案2】:

您实际上可以保留文件原样,使用逗号作为分隔符。您只需使用 getline 指定不同的分隔符。

std::getline(input, target_string, ',')

其中 target_string 是 book[index].author、title 或其他属性。

对于该行的最后一个属性,您可以使用:

std::getline(input, target_string)

换行符是默认分隔符。

【讨论】:

  • 和这个一样吗?:input.getline(book[index].author, ','); ..... input.getline(book[index].category[k].genre, '\n');
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-03
  • 2023-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多