从文件读取不会读取整个文件,重制[关闭]

问题描述 投票:0回答:0

因此,对于学校的工作,我必须从文件中打印行,但是我的问题发生在读取函数上,它不会读取文件中的每一行,而是读取一行,跳过下一行,然后读取下一行之后一行,然后重复。我尝试读取的文件有 220 行,但我的程序却打印了 110 行。 主文件:

#define _CRT_SECURE_NO_WARNING
#include <iostream>
#include <fstream>
#include "Book.h"
#include "Date.h"


using namespace std;
using namespace sdds;

Book readBook(istream& istr) {
    Book P;
    istr >> P;
    return P;
}
Book getNextRec(ifstream& ifstr) {
    Book P;
    ifstr >> P;
    ifstr.ignore(1000, '\n');
    return P;
}

int main() {
    Book pd;
    cout << endl << "Contents of the file:" << endl;
    ifstream filein("Books.txt");
    char pType{};
    for (int row = 1; filein; row++) {
        filein >> pType;
        if (pType != 'B') {
            cout << "The Record type signature is supposed to be B, but it is: " << pType << endl;
            filein.setstate(ios::failbit);
        }
        filein.ignore();
        pd = getNextRec(filein);
        if (filein) {
            cout << (pd.onLoan() ? "|*" : "| ");
            cout.width(4);
            cout.fill(' ');
            cout.setf(ios::right);
            cout << row << (pd.onLoan() ? "*" : " ");
            cout.unsetf(ios::right);
            cout << pd << (pd == "Star" ? "<<<" : "") << endl;
        }
    }
    return 0;
}

流媒体模块: 可流式传输.cpp

#include "Streamable.h"

namespace sdds {
    Streamable::~Streamable(){};
    std::ostream& operator<<(std::ostream& os, const Streamable& s) {
        if (s) {
            s.write(os);
        }
        return os;
    }

    std::istream& operator>>(std::istream& is, Streamable& s) {
        return (s.read(is));
    }
}

可流式传输.h

#ifndef SDDS_STREAMABLE_H
#define SDDS_STREAMABLE_H

#include <iostream>

namespace sdds {
    class Streamable {
    public:
        virtual std::ostream& write(std::ostream& os) const = 0;
        virtual std::istream& read(std::istream& is) = 0;
        virtual bool conIO(std::ios& io) const = 0;
        virtual operator bool() const = 0;
        virtual ~Streamable();
    };
    std::ostream& operator<<(std::ostream& os, const Streamable& s);
    std::istream& operator>>(std::istream& is, Streamable& s);
}

#endif //SDDS_STREAMABLE_H

图书模块: 书本.cpp

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <iomanip>
#include "Book.h"
using namespace std;



namespace sdds {

    Book::Book() : m_author(nullptr) {}

    Book::~Book() {
        delete[] m_author;
    }

    Book::Book(const Book& other) : Publication(other) {
        if (other.m_author != nullptr) {
            m_author = new char[strlen(other.m_author) + 1];
            strcpy(m_author, other.m_author);
        }
        else {
            m_author = nullptr;
        }
    }

    Book& Book::operator=(const Book& other) {
        if (this != &other) {
            Publication::operator=(other);
            delete[] m_author;
            if (other.m_author != nullptr) {
                m_author = new char[strlen(other.m_author) + 1];
                strcpy(m_author, other.m_author);
            }
            else {
                m_author = nullptr;
            }
        }
        return *this;
    }

    char Book::type() const {
        return 'B';
    }

    std::ostream& Book::write(std::ostream& os) const {
        Publication::write(os);
        if (conIO(os)) {
            os << ' ';
            os.width(15); os << fixed << left << setfill(' ') << std::string(m_author).substr(0, 15) << " |";
        }
        else {
            os << '\t' << m_author;
        }
        return os;
    }

    std::istream& Book::read(std::istream& istr) {
        delete[] m_author;
        m_author = nullptr;
        if (conIO(istr)) {
            Publication::read(istr);
            istr.ignore();
            std::cout << "Author: ";
            char author[256];
            istr.getline(author, 256);
            m_author = new char[strlen(author) + 1];
            strcpy(m_author, author);
        }
        else {
            Publication::read(istr);
            istr.ignore();
            char author[256];
            istr.getline(author, 256); 
            if (istr) {
                m_author = new char[strlen(author) + 1];
                strcpy(m_author, author);
            }
        }
        return istr;
    }

    void Book::set(int member_id) {
        Publication::set(member_id);
        resetDate();
    }

    std::ostream& operator<<(std::ostream& os, const Book& book) {
        return book.write(os);
    }
    std::istream& operator>>(std::istream& is, Book& book) {
        return book.read(is);
    }

    Book::operator bool() const {
        return m_author && m_author[0] != '\0' && Publication::operator bool();
    }
}

书.h

#ifndef SDDS_BOOK_H
#define SDDS_BOOK_H
#include "Publication.h"

namespace sdds {
    class Book : public Publication {
        char* m_author;
    public:
        Book();
        Book(const Book& other);
        Book& operator=(const Book& other);
        ~Book();

        char type() const override;
        std::ostream& write(std::ostream& os) const override;
        std::istream& read(std::istream& istr) override;
        void set(int member_id) override;
        operator bool() const override;
    };
}

#endif // !SDDS_BOOK_H

发布模块: 出版物.cpp

#define _CRT_SECURE_NO_WARNINGS
#include "Publication.h"
#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;

namespace sdds {
    Publication::Publication() {
        setDefault();
    }

    Publication::~Publication() {
        delete[] m_title;
    }

    void Publication::setDefault() {
        m_title = nullptr;
        m_shelfId[0] = '\0';
        m_membership = 0;
        m_libRef = -1;
        resetDate();
    }

    void Publication::resetDate() {
        m_date = Date();
    }

    char Publication::type() const {
        return 'P';
    }

    bool Publication::conIO(std::ios& io) const {
        return (&io == &std::cin || &io == &std::cout);
    }

    ostream& Publication::write(ostream& os) const {
        if ((m_title != nullptr) && m_shelfId[0] != '\0') {
            if (m_title[0] != '\0' && m_date) {
                if (conIO(os)) {
                    os << "| " << m_shelfId << " | ";
                    os.width(30);
                    os << left << setfill('.') << std::string(m_title).substr(0, 30) << " | ";
                    if (m_membership > 0) {
                        os << m_membership;
                    }
                    else {
                        os << " N/A ";
                    }
                    os << " | " << m_date << " |";
                }
                else {
                    os << '\n' << type() << '\t' << m_libRef << '\t' << m_shelfId << '\t' << m_title << '\t';
                    if (m_membership > 0) {
                        os << m_membership;
                    }
                    os << '\t' << m_date;
                }
            }
            
        }

        return os;
    }

    std::istream& Publication::read(std::istream& is) {
        char t_title[SDDS_TITLE_WIDTH + 1]{}, t_shelfId[SDDS_SHELF_ID_LEN + 1]{};
        int t_libRef = -1, t_membership = 0;
        Date t_date;

        if (m_title) {
            delete[] m_title;
            m_title = nullptr;
        }
        setDefault();

        if (conIO(is)) {
            std::cout << "Shelf No: ";
            is.getline(t_shelfId, SDDS_SHELF_ID_LEN + 1);

            if (strlen(t_shelfId) != SDDS_SHELF_ID_LEN) {
                is.setstate(std::ios::failbit);
            }

            std::cout << "Title: ";
            is.getline(t_title, SDDS_TITLE_WIDTH + 1);

            std::cout << "Date: ";
            is >> t_date;
        }

        else {
            is >> t_libRef;
            is.ignore();
            is.getline(t_shelfId, SDDS_SHELF_ID_LEN + 1, '\t');
            is.getline(t_title, SDDS_TITLE_WIDTH + 1, '\t');
            is >> t_membership;
            is.ignore();
            is >> t_date;
        }

        if (!t_date) {
            is.setstate(std::ios::failbit);
        }

        if (is) {
            m_title = new char[strlen(t_title) + 1];
            strcpy(m_title, t_title);
            strcpy(m_shelfId, t_shelfId);
            m_membership = t_membership;
            m_date = t_date;
            m_libRef = t_libRef;
        }

        return is;
    }

    Publication::operator bool() const {
        return m_title != nullptr && m_shelfId[0] != '\0';
    }

    std::ostream& operator<<(std::ostream& os, const Publication& publication) {
        return publication.write(os);
    }
    std::istream& operator>>(std::istream& is, Publication& publication) {
        return publication.read(is);
    }
}

出版.h

#ifndef SDDS_PUBLICATION_H
#define SDDS_PUBLICATION_H

#include "Lib.h"
#include "Streamable.h"
#include "Date.h"

namespace sdds {
    class Publication : public Streamable {
        char* m_title;
        char m_shelfId[SDDS_SHELF_ID_LEN + 1];
        int m_membership;
        int m_libRef;
        Date m_date;

    public:
        Publication();
        ~Publication();
        void setDefault();
        void resetDate();
        virtual char type() const;
        bool conIO(std::ios& io) const;
        std::ostream& write(std::ostream& os) const;
        std::istream& read(std::istream& istr);
        operator bool() const;

日期模块: 日期.cpp

#define _CRT_SECURE_NO_WARNINGS
#include <iomanip>
#include <iostream>
#include <ctime>
#include "Date.h"
using namespace std;

namespace sdds {
    bool sdds_test = false;
    int sdds_year = 2023;
    int sdds_mon = 12;
    int sdds_day = 25;

    bool Date::validate()
    {
        errCode(NO_ERROR);
        if (m_year < MIN_YEAR || m_year > m_CUR_YEAR + 1)
        {
            errCode(YEAR_ERROR);
        }
        else if (m_mon < 1 || m_mon > 12)
        {
            errCode(MON_ERROR);
        }
        else if (m_day < 1 || m_day > mdays())
        {
            errCode(DAY_ERROR);
        }
        return !bad();
    }

    int Date::mdays() const
    {
        int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, -1 };
        int mon = m_mon >= 1 && m_mon <= 12 ? m_mon : 13;
        mon--;
        return days[mon] + int((mon == 1) * ((m_year % 4 == 0) && (m_year % 100 != 0)) || (m_year % 400 == 0));
    }

    int Date::systemYear()const {
        int theYear = sdds_year;
        if (!sdds_test) {
            time_t t = time(NULL);
            tm lt = *localtime(&t);
            theYear = lt.tm_year + 1900;
        }
        return theYear;
    }

    void Date::setToToday() {
        if (sdds_test) {
            m_day = sdds_day;
            m_mon = sdds_mon;
            m_year = sdds_year;
        }
        else {
            time_t t = time(NULL);
            tm lt = *localtime(&t);
            m_day = lt.tm_mday;
            m_mon = lt.tm_mon + 1;
            m_year = lt.tm_year + 1900;
        }
        errCode(NO_ERROR);
    }

    int Date::daysSince0001_1_1() const
    { // Rata Die day since 0001/01/01
        int ty = m_year;
        int tm = m_mon;
        if (tm < 3)
        {
            ty--;
            tm += 12;
        }
        return 365 * ty + ty / 4 - ty / 100 + ty / 400 + (153 * tm - 457) / 5 + m_day - 306;
    }

    Date::Date() : m_CUR_YEAR(systemYear())
    {
        setToToday();
    }

    Date::Date(int year, int mon, int day) : m_CUR_YEAR(systemYear())
    {
        m_year = year;
        m_mon = mon;
        m_day = day;
        validate();
    }

    const char* Date::dateStatus() const
    {
        return DATE_ERROR[errCode()];
    }

    int Date::currentYear() const
    {
        return m_CUR_YEAR;
    }

    void Date::errCode(int readErrorCode)
    {
        m_ErrorCode = readErrorCode;
    }

    int Date::errCode() const
    {
        return m_ErrorCode;
    }

    bool Date::bad() const
    {
        return m_ErrorCode != 0;
    }

    std::istream& Date::read(std::istream& is)
    {
        errCode(NO_ERROR);
        is >> m_year;
        is.ignore();
        is >> m_mon;
        is.ignore();
        is >> m_day;

        if (!is)
        {
            errCode(CIN_FAILED);
        }
        else
        {
            validate();
        }

        return is;
    }
    std::ostream& Date::write(std::ostream& os) const
    {
        if (bad()) {
            os << dateStatus();
        }
        else {
            os << m_year << "/";
            os << setfill('0') << setw(2) << right << m_mon << "/";
            os << setfill('0') << setw(2) << right << m_day;
        }

        return os;
    }

    int Date::getdaysSince0001_1_1() const
    {
        return daysSince0001_1_1();
    }

    Date::operator bool() const
    {
        return (!bad());
    }

    std::ostream& operator<<(std::ostream& os, const Date& RO) {
        return RO.write(os);
    }

    std::istream& operator>>(std::istream& is, Date& RO){
        return RO.read(is);
    }

    int numberOfDaysInMonth(int monthByNumber, int year)
    {
        int numberOfDays = 0;
        int arr[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

        if (monthByNumber == 2 && ((year % 400 == 0) || ((year % 100 != 0) && (year % 4 == 0))))
        {
            numberOfDays = arr[monthByNumber - 1] + 1;
        }

        else
        {
            numberOfDays = arr[monthByNumber - 1];
        }

        return numberOfDays;
    }
}

日期.h

#ifndef SDDS_DATE_H__
#define SDDS_DATE_H__
#include <iostream>
namespace sdds
{
    const int NO_ERROR = 0;
    const int CIN_FAILED = 1;
    const int YEAR_ERROR = 2;
    const int MON_ERROR = 3;
    const int DAY_ERROR = 4;
    const char DATE_ERROR[5][16] = {
        "No Error",
        "cin Failed",
        "Bad Year Value",
        "Bad Month Value",
        "Bad Day Value" };
    const int MIN_YEAR = 1500;
    class Date
    {
    private:
        int m_year;
        int m_mon;
        int m_day;
        int m_ErrorCode;
        int m_CUR_YEAR;
        int daysSince0001_1_1() const; // returns number of days passed since the date 0001/1/1
        bool validate();               /* validates the date setting the error code and then returning the result
                                        true, if valid, and false if invalid.*/
        void errCode(int);             // sets the error code
        int systemYear() const;        // returns the current system year
        bool bad() const;              // return true if
        int mdays() const;             // returns the number of days in current month
        void setToToday();             // sets the date to the current date (system date)
    public:
        Date();                           // creates a date with current date
        Date(int year, int mon, int day); /* create a date with assigned values
                                           then validates the date and sets the
                                           error code accordingly */
        int errCode() const;              // returns the error code or zero if date is valid
        const char* dateStatus() const;   // returns a string corresponding the current status of the date
        int currentYear() const;          // returns the m_CUR_YEAR value;

        int getdaysSince0001_1_1() const;

        operator bool() const;

        std::istream& read(std::istream& is = std::cin);

        std::ostream& write(std::ostream& os = std::cout) const;
    };

    std::ostream& operator<<(std::ostream& os, const Date& RO);
    std::istream& operator>>(std::istream& is, Date& RO);

    int numberOfDaysInMonth(int monthByNumber, int year);
}

Lib.h:

#ifndef SDDS_LIB_H
#define SDDS_LIB_H

namespace sdds {
    const int SDDS_MAX_LOAN_DAYS = 15;
    const int SDDS_TITLE_WIDTH = 50;
    const int SDDS_AUTHOR_WIDTH = 15;
    const int SDDS_SHELF_ID_LEN = 4;
    const int SDDS_LIBRARY_CAPACITY = 5000;
}

#endif //SDDS_LIB_H

这是我在代码中使用的所有文件和函数。

我尝试更改ignore()或在getline()之后添加另一个。我尝试更改数组和 getline() 中的字符数。但没有任何效果。

c++ file fstream
© www.soinside.com 2019 - 2024. All rights reserved.