我正在创建一个图书馆管理,你可以添加书籍,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
答案 0 :(得分:2)
虽然以下不是您问题的确切原因,但可能会导致问题。
使用C-Style(char *)字符串有很多方法可以使程序失败。还有内存管理问题。
请改用std::string
。如果需要固定的记录长度,可以在写入数据时进行处理。所有其他时间你应该使用std::string
。
此外,您可以将operator ==
与std::string
一起使用,而不是strcmp
。如果两个字符串不是nul终止的话,strcmp
函数将调用未定义的行为。
fgets
fgets
存在缓冲区溢出和其他问题。请改用std::getline
和std::string
。此组合将根据需要处理扩展字符串。它更安全。
保持一致,使用C ++流或C风格的I / O,不要混淆两者。例如,您使用cout
并使用相同的函数puts
。两者可能使用不同的I / O缓冲区。我不明白为什么你不使用cout << name;
。
C ++语言有一种表示true
和false
值的类型。类型为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()
因为它不会显示所需的结果