因此,对于学校的工作,我必须从文件中打印行,但是我的问题发生在读取函数上,它不会读取文件中的每一行,而是读取一行,跳过下一行,然后读取下一行之后一行,然后重复。我尝试读取的文件有 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() 中的字符数。但没有任何效果。