我正在编写一个程序,用于在随机访问文件中维护员工数据库。它必须具备添加员工和删除员工(通过将记录中的所有空格写入)的功能。这是我目前的进展情况,但它并不完全正确。当读取员工时,它会读取正确记录的薪水,但是下一条记录的名字。此外,当我删除最后一条记录然后在该记录中添加一个员工时,我无法查看员工信息,会出现异常错误。
我并不寻求解决方案,只是需要一点指引方向。谢谢。
好的,这里是新的改进代码(我认为如此)。唯一的问题是在添加雇员时,如果有空记录,程序可以将其添加到第一个空记录中,但如果没有空记录,则不能将其添加到文件末尾而不会影响添加到第一个空记录。我的意思是,如果有空记录,它会将雇员添加到记录中,但如果没有空记录,则不会将雇员添加到文件末尾。如果我添加代码以添加到文件末尾,则会发生两种情况之一:要么它添加到空记录中,然后请求添加另一个雇员并将其添加到末尾,要么只是跳过空记录并添加到文件末尾。
不太确定我做错了什么,但感谢任何提示。
我并不寻求解决方案,只是需要一点指引方向。谢谢。
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include "ccc_empl.h"
using namespace std;
const int NEWLINE_LENGTH = 2;
const int RECORD_SIZE = 30 + 10 + NEWLINE_LENGTH;
/**
converts a string to a floating-point value
@param s a string representing a floating-point value
@return the equivalent floating-point value
*/
double string_to_double(string s)
{
istringstream instr(s);
double x;
instr >> x;
return x;
}
/*
reads an employee record from the input file
@param e the employee
@param in the file to read from
*/
Employee read_employee(istream& in)
{
string line;
getline(in, line);
string input_name = line.substr(0, 30);
double input_salary = string_to_double(line.substr(30, 10));
Employee e(input_name, input_salary);
return e;
}
/*
gets input for an Employee object
@param input_name the name of the employee
@param input_salary the salary of the employee
@param e the Employee object
@return returns the Employee object
*/
Employee input_employee()
{
string input_name;
cout << "Name: ";
cin.ignore();
getline(cin, input_name);
cout << "Salary: ";
double input_salary;
cin >> input_salary;
Employee e(input_name, input_salary);
return e;
}
/**
adds an employee record to a file
@param e the employee record to write
@param out the file to write to
*/
void add_employee(Employee e, ostream& out)
{
out << e.get_name()
<< setw(30)
<< fixed << setprecision(2)
<< e.get_salary();
}
/**
removes an employee record from a file
@param e the employee record to remove
@param out the file to remove from
*/
void remove_employee(ostream& out)
{
out << " " << setw(42) << fixed << setprecision(2) << " \n";
}
int main()
{
cout << "Please enter the data file name: ";
string filename;
cin >> filename;
fstream fs;
fs.open(filename);
fs.seekg(0, ios::end); // Go to end of file
int nrecord = fs.tellg() / RECORD_SIZE; // determine number of records in the file
int menu_input = 0;
string input_name;
double input_salary = 0;
while (menu_input != 4)
{
cout << "Please enter the record to update: (0 - " << nrecord - 1 << ") exit to quit ";
int pos = 0;
cin >> pos;
if(cin.fail())
{
cout << "Exiting..." << endl;
system("pause");
return 0;
}
// menu for user input
cout << "\nWhat action would you like to perform?" << endl;
cout << "Add employee.....1" << endl;
cout << "Remove employee..2" << endl;
cout << "View employee....3" << endl;
cin >> menu_input;
switch(menu_input)
{
case 1: fs.seekg(pos * RECORD_SIZE, ios::beg);
add_employee(input_employee(), fs);
break;
case 2: fs.seekg(pos * RECORD_SIZE, ios::beg);
remove_employee(fs);
break;
case 3: fs.seekg(pos * RECORD_SIZE, ios::beg);
cout << "\nName: " << read_employee(fs).get_name() << "Salary: " << read_employee(fs).get_salary() << endl << endl;
break;
default: cout << "Invalid entry" << endl;
break;
}
}
fs.close();
system("pause");
return 0;
}
好的,这里是新的改进代码(我认为如此)。唯一的问题是在添加雇员时,如果有空记录,程序可以将其添加到第一个空记录中,但如果没有空记录,则不能将其添加到文件末尾而不会影响添加到第一个空记录。我的意思是,如果有空记录,它会将雇员添加到记录中,但如果没有空记录,则不会将雇员添加到文件末尾。如果我添加代码以添加到文件末尾,则会发生两种情况之一:要么它添加到空记录中,然后请求添加另一个雇员并将其添加到末尾,要么只是跳过空记录并添加到文件末尾。
不太确定我做错了什么,但感谢任何提示。
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include "ccc_empl.h"
using namespace std;
const int NEWLINE_LENGTH = 2;
const int RECORD_SIZE = 30 + 10 + NEWLINE_LENGTH;
/**
converts a string to a floating-point value
@param s a string representing a floating-point value
@return the equivalent floating-point value
*/
double string_to_double(string s)
{
istringstream instr(s);
double x;
instr >> x;
return x;
}
/*
reads an employee record from the input file
@param e the employee
@param in the file to read from
*/
Employee read_employee(istream& in)
{
string line;
getline(in, line);
string input_name = line.substr(0, 30);
double input_salary = string_to_double(line.substr(30, 10));
Employee e(input_name, input_salary);
return e;
}
/*
gets input for an Employee object
@param input_name the name of the employee
@param input_salary the salary of the employee
@param e the Employee object
@return returns the Employee object
*/
Employee input_employee()
{
string input_name;
cout << "Name: ";
cin.ignore();
getline(cin, input_name);
cout << "Salary: ";
double input_salary;
cin >> input_salary;
Employee e(input_name, input_salary);
return e;
}
/**
adds an employee record to a file
@param e the employee record to write
@param out the file to write to
*/
void add_employee(Employee e, ostream& out)
{
out << e.get_name()
<< setw(10 + 30 - e.get_name().length())
<< fixed << setprecision(2)
<< e.get_salary() << "\n";
}
/**
removes an employee record from a file
@param e the employee record to remove
@param out the file to remove from
*/
void remove_employee(ostream& out)
{
out << " " << setw(40) << fixed << setprecision(2) << " \n";
}
int main()
{
cout << "Please enter the data file name: ";
string filename;
cin >> filename;
fstream fs;
fs.open(filename);
fs.seekg(0, ios::end); // Go to end of file
int nrecord = fs.tellg() / RECORD_SIZE; // determine number of records in the file
int menu_input = 1;
string input_name;
double input_salary = 0;
while (menu_input)
{
// menu for user input
cout << "\nWhat action would you like to perform?" << endl;
cout << "Add employee.....1" << endl;
cout << "Remove employee..2" << endl;
cout << "View employee....3" << endl;
cout << "Exit.............4" << endl;
cin >> menu_input;
if (menu_input == 4)
{
cout << "\nExiting..." << endl << endl;
system("pause");
return 0;
}
// switch statment to perform selected menu_input task
switch(menu_input)
{
case 1: // adds an employee in the first empty record
// or at the end of the file if no records are empty
{
int count = 0;
string s;
for (int i = 0; i < nrecord; i++)
{
fs.seekp(count, ios::beg);
getline(fs, s);
if (isspace(s[0]))
{
fs.seekp(count, ios::beg);
add_employee(input_employee(), fs);
nrecord++;
break;
}else
count += 42;
}
}
break;
case 2: {
cout << "Please enter the record to remove: (0 - " << nrecord -1 << ") ";
int pos = 0;
cin >> pos;
fs.seekp(pos * RECORD_SIZE, ios::beg);
remove_employee(fs);
}
break;
case 3: {
cout << "Please enter the record to view: (0 - " << nrecord -1 << ") ";
int pos = 0;
cin >> pos;
fs.seekg(pos * RECORD_SIZE, ios::beg);
Employee e(read_employee(fs));
cout << "\nName: " << e.get_name() << "Salary: " << e.get_salary() << endl << endl;
}
break;
default: cout << "Invalid entry" << endl;
break;
}
}
fs.close();
system("pause");
return 0;
}
stod
和strtod
这样的东西可以将字符串转换为双精度浮点数。不需要自己写。 - chris