为什么我的图书馆管理程序没有写入文件

时间:2015-04-08 14:34:53

标签: c++ oop

我正在创建一个图书馆管理,你可以添加书籍,DVD和学生。然后可以向学生发放书籍和DVD。书籍,DVD和学生被写入.dat文件。

我遇到的问题是该程序似乎没有将学生写入.dat文件,因此当我搜索学生或尝试发书学生时,它找不到学生,它给我一个错误,说学生没找到。有人能告诉我我做错了什么。

我已经包含了下面的一些代码。 Main.cpp的

#include <iostream>
#include "Library.h"

int main() {
    Library lib1;
while(1)
    {
                char studentOption;
                char name[30];

                std::cout<<"1 to add a new student\n";
                std::cout<<"2 to search for a student\n";

                std::cin.getline( name, 80);
                studentOption = name[0];

                switch(studentOption){
                    case '1':
                        lib1.insertStudent();
                        break;
                    case '2':
                        char regno[6];
                        std::cout<<"Enter the registration no. of the student you            want to search: \n";
                        std::cin>>regno;
                        lib1.searchStudent(regno);
                        break;
                }
};

    return 0;
};

Library.h

#ifndef _Library_H_
#define _Library_H_
#include <stdio.h>

class Library
{
public:
void insertStudent();
    void searchStudent(char regno[]);
};

#endif 

Library.cpp

 #include <iostream>
    #include <fstream>
    #include "Library.h"
    #include "Student.h"

    Student student1;

    void Library::insertStudent()
    {
        std::fstream file;
        file.open("student.dat",std::ios::out|std::ios::app);
        student1.newStudent();
        file.write((char*)&student1,sizeof(Student));
        file.close();
    }

    void Library::searchStudent(char regno[])
    {
        std::fstream file;
        int flag=0;
        file.open("student.dat",std::ios::in);
        while(file.read((char*)&student1,sizeof(Student)))
        {
            if((strcmp(student1.retregistrationNo(),regno)==0))
            {
                student1.displayStudent();
                flag=1;
            }
        }

        file.close();
        if(flag==0)
            std::cout<<"Error: Student not found in the system. \n";
    }

Student.cpp

#include "Student.h"
void Student::newStudent()
{
    std::cout<<"Enter the registration no. \n";
    std::cin>>registrationno;
    std::cin.ignore();
    std::cout<<"Enter the name of the student \n";
    fgets(name, sizeof(name), stdin);
    stbookbar[0]='/0';
    std::cout<<"Student added to system.\n";
}
void Student::displayStudent()
{
    std::cout<<"Enter the registration no. : \n";
    std::cin>>registrationno;
    std::cin.ignore();
    std::cout<<"Enter the name of the student: \n";
    puts(name);
}

Student.h

#ifndef STUDENT_H_
#define STUDENT_H_

#include <iostream>
#include <fstream>

class Student
{
    char registrationno[6];
    char name[20];
    char stbookbar[6];
    char stdvdbar[6];
public:
    void newStudent();
    void displayStudent();

    char* retregistrationNo()
    {
        return registrationno;
    }
}; 
#endif 

2 个答案:

答案 0 :(得分:2)

虽然以下不是您问题的确切原因,但可能会导致问题。

使用字符串而不是char *

使用C-Style(char *)字符串有很多方法可以使程序失败。还有内存管理问题。

请改用std::string。如果需要固定的记录长度,可以在写入数据时进行处理。所有其他时间你应该使用std::string

此外,您可以将operator ==std::string一起使用,而不是strcmp。如果两个字符串不是nul终止的话,strcmp函数将调用未定义的行为。

避免fgets

fgets存在缓冲区溢出和其他问题。请改用std::getlinestd::string。此组合将根据需要处理扩展字符串。它更安全。

不要越过溪流

保持一致,使用C ++流或C风格的I / O,不要混淆两者。例如,您使用cout并使用相同的函数puts。两者可能使用不同的I / O缓冲区。我不明白为什么你不使用cout << name;

使用布尔类型,而不是1&amp; 0

C ++语言有一种表示truefalse值的类型。类型为bool,使用它。布尔值的1和0表示是老式的(如大约1966年)。转到更易读的代码。

使用整数,值3是真还是假? -1怎么样?通过阅读代码,将整数设置为0的原因远远多于将布尔变量设置为 false 的原因。

可读代码可防止许多缺陷。

始终使用块语句。

所有if, for, while, do-while都应该使用块 将编码样式更改为单行和多行语句使用“{”和“}”。

避免使用魔数

幻数是一个没有任何描述的数字常量。更喜欢命名标识符。命名标识符使代码更易于阅读和维护。

例如,假设您有一个容量为23个字符的文本字段。如果将容量更改为32,则必须查找每次出现的23,确定实例是否适用于文本字段,然后修改它们。使用命名标识符,您只需进行1次更改,这就是声明标识符的位置。

使用调试器

立即投入时间学习使用调试器。您可以自己找到更快的问题而不必等待某人回复您的帖子。

使用测试用例

设计您的程序,以便它可以读取测试用例。将数据放入文件并将其提供给您的程序。创建通过的测试用例。 创建无效的测试用例,这些将破坏您的程序。您的程序可以处理无效输入吗?

测试用例允许自动测试您的程序。在调试问题时,它们还允许一致的操作。

编辑1:比较字符串
例如:

std::string s1 = "Taco";
std::string s2 = "Salad";
if (s1 == s2)
{
  cout << "s1 == s2\n";
}
if (s1 == "burrito")
{
  cout << "s1 == burrito\n";
}

答案 1 :(得分:1)

正如@NathanOliver在评论中已经指出的那样,你需要以二进制模式打开文件才能读取字节并将它们放在student1变量中

file.open("student.dat",std::ios::in | std::ios::binary);

并更正

的内码
displayStudent()

因为它不会显示所需的结果