c++ - 文件只读取 1 条记录,然后到达文件末尾,即使还有其他记录

标签 c++

所以我接到了一个任务,要创建一个类似程序的库 我被指示对添加的书籍进行不同的操作(添加书籍,删除..)

addbook 函数将 book 对象写入文件,并且 book 的每条记录都有一个 endl 分隔符(以便我稍后可以使用 getline 获取记录)

printbook 函数只是获取 book 对象并将其打印出来

我的问题是当我试图打印文件中的所有书籍记录(代码写在 main 中)时它只读取第一条记录并且显然它在之后立即到达文件末尾 即使它没有读取文件中的其余记录

我的问题是它怎么可能在不读取整个文件的情况下到达文件末尾,我该如何解决这个问题以便我可以读取已写入文件的所有记录

#include<iostream>
#include<fstream>
#include<strstream>
#include <cstring>
using namespace std;

struct book{
    char ISBN[6];
    char TITLE[100];
    char AUTHOR_NAME[100];
    float PRICE;
    int YEAR;
    int NUM_PAGES;

    book(char* isbn = "" , char* title = "" , char* author = "" , float price = 0 , int year = 0, int nPages = 0){
        strcpy(ISBN ,isbn);
        strcpy(TITLE , title);
        strcpy(AUTHOR_NAME ,author);
        PRICE = price;
        YEAR = year;
        NUM_PAGES = nPages;
    }

};

void printBook(book b);
void addBook(fstream& file );
//void deleteBook(fstream& file , int isbn);
//void updateBook(fstream& file , int isbn);
//void printBookByTitle(fstream& file , char* title);
//void printAll(fstream& file);

void addBook(fstream& file ){
    cout << "\nplease enter your book's \n1- ISBN\n2- title \n3- author name \n4- price \n5- year \n6- number of pages\n";
    book b;

    cin.getline(b.ISBN , 6);
    cin.getline(b.TITLE ,100);
    cin.getline(b.AUTHOR_NAME ,100);
    cin >> b.PRICE;
    cin >> b.YEAR;
    cin >> b.NUM_PAGES;

    cin.ignore();

    file.write((char*)& b ,sizeof(b));
    file<<'\n';
}
void printBook(book b){
    cout << "the book's ISPN is " << b.ISBN << endl;
    cout << "the title of this book is " << b.TITLE << endl;
    cout << "the author is " << b.AUTHOR_NAME << endl;
    cout << "the book's price is "<<b.PRICE<< endl;
    cout << "the year by which was published is "<< b.YEAR << endl;
    cout << "the number of pages on this book is " << b.NUM_PAGES << endl << endl;
}
int main()
{

    fstream file;
    file.open("farah.txt" , ios::out | ios::in );

    book b;
    addBook(file);
    addBook(file);
    addBook(file);


    file.seekg(0);

    do{
        file.getline((char*)& b , sizeof(b)+1);
        printBook(b);
    }while(!file.eof()-1);

    return 0;
}

最佳答案

file.write((char*)& b ,sizeof(b));
file<<'\n';

所以你写出一个原始记录,它可能会或可能不会恰好包含换行符,然后写出一个换行符。

    file.getline((char*)& b , sizeof(b)+1);

然后您使用getline 尝试读回它。但这是行不通的。根据定义,一行以换行符结束。因此,如果由读取行的函数读取,记录可能会占用多行。

尺寸加一会造成很大的问题。当您的实现看到 book b 时,它知道分配 sizeof(book) 字节来保存该对象。但是随后您读取的字节数超过了该数量——写入您尚未分配的内存,可能会踩到其他对象或导致访问冲突。

你有几个选择:

您可以使用原始读取函数读取 sizeof(b) 字节,然后读取换行符。您可以使用原始读取功能并摆脱换行符。您可以在写出记录时将记录格式化为一行,然后使用读取行的函数将其读入。

最后,您还滥用了 eof。您正试图用它来预测 future ,也就是说,告诉您 future 的读取是否会成功。但 eof 是一个状态报告函数(如 selectstatfsaccess 等),而不是 future 预测功能。相反,查看读取是否真正成功,而不是在执行之前尝试以某种方式确保它不会失败。

关于c++ - 文件只读取 1 条记录,然后到达文件末尾,即使还有其他记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55011083/

相关文章:

C++ 异常规范 - 处理无效异常

c++ - 下载文件的 CMake 检查哈希 (MD5/SHA256)

c++ - 暴露私有(private)内部类大小

c++ - 获取错误 'char16_t and char32_t undeclared'

c++ - 初始化枚举 C++

c++ - 在两个语句中创建引用变量

c++ - 为什么 C++ 映射中没有 "exists"函数?

c++ - 如何使用复合键获取 boost::multi_index_container 中第一个键的不同计数

c++ - c++同时处理多个文件

c++ - 两种类型的构造函数重载