尝试从结构中编写二进制文件。不幸的是,它写出了过多的空格,因为我的字符串长度都是20个字符。我会使用指针,但我的教科书明确指出不使用指针(即记住:在写入二进制文件时只使用固定大小的数据成员。不要使用包含指针作为数据成员的指针或类)。
更糟糕的是,我试图打印的数字(即8和40)只显示为“A”和“B”。
输出看起来像这样
Employee.dat (我写的二进制文件)
Pauline Nordin A B
但我希望它看起来像这样。
Pauline Nordin 8.00 40.00
这是我的代码:
摘自protocol.cpp
//Open file
std::ifstream BinaryOpen("employee.txt", std::ios::in /*| std::ios::out*/ | std::ios::binary);
//Check if file is open
if(BinaryOpen.is_open())
{
//Priming read
BinaryOpen >> favoriteEmployees[numberOfEmployees].firstName;
BinaryOpen >> favoriteEmployees[numberOfEmployees].lastName;
BinaryOpen >> favoriteEmployees[numberOfEmployees].hourlyWage;
BinaryOpen >> favoriteEmployees[numberOfEmployees].hoursWorked;
numberOfEmployees++;
//Read file
while(!BinaryOpen.eof())
{
BinaryOpen >> favoriteEmployees[numberOfEmployees].firstName;
BinaryOpen >> favoriteEmployees[numberOfEmployees].lastName;
BinaryOpen >> favoriteEmployees[numberOfEmployees].hourlyWage;
BinaryOpen >> favoriteEmployees[numberOfEmployees].hoursWorked;
numberOfEmployees++;
//Close file
BinaryOpen.close();
}
//Write to binary file
std::ofstream BinaryWrite("employee.dat", std::ios::out | std::ios::binary);
//Check if file opened
if(BinaryWrite.is_open())
{
BinaryWrite.write(reinterpret_cast <char *>(favoriteEmployees),
sizeof(Employee) * numberOfEmployees);
//Close file
BinaryWrite.close();
}
else
std::cout << "\nWrite file did not open! " << std::endl;
}
else
std::cout << "\nFile did not open! " << std::endl;
}
以下是我的程序的所有文件:
employee.txt (即我正在阅读的文件)
Pauline Nordin 8.00 40.00
的main.cpp
#include <iostream>
#include "protocol.h"
#include "employee.h"
int main()
{
int menuChoice = 0;
int numberOfEmployees = 0;
//Create array of employees
Employee favoriteEmployees[NUMBER_OF_EMPLOYEES];
//To prevent garbage being printed out
for(int i = 0; i < BUFFER_LENGTH; i++)
{
favoriteEmployees[0].firstName[i] = 0;
favoriteEmployees[0].lastName[i] = 0;
favoriteEmployees[0].hourlyWage = 0;
favoriteEmployees[0].hoursWorked = 0;
}
PrintMenu();
GetMenuChoice(menuChoice);
ExecuteMenuChoice(menuChoice, favoriteEmployees, numberOfEmployees);
return 0;
}
protocol.h
#ifndef PROTOCOL_H
#define PROTOCOL_H
#include "employee.h"
const int NUMBER_OF_EMPLOYEES = 10;
//Function declarations
void PrintMenu();
void GetMenuChoice(int &menuChoice);
void ExecuteMenuChoice(int menuChoice, Employee favoriteEmployees[], int &numberOfEmployees);
#endif
protocol.cpp
#include <fstream>
#include <iostream>
#include "employee.h"
#include "protocol.h"
//Function definitions
void PrintMenu()
{
std::cout << "\n\nChapter 17 -- Learn By Doings " << std::endl;
std::cout << "\n1. Learn By Doing 17.2 " << std::endl;
std::cout << "2. Learn By Doing 17.3 " << std::endl;
std::cout << "3. Learn By Doing 17.4 " << std::endl;
std::cout << "4. Exit " << std::endl;
std::cout << ' ' << std::endl;
}
void GetMenuChoice(int &menuChoice)
{
std::cin >> menuChoice;
}
void ExecuteMenuChoice(int menuChoice, Employee favoriteEmployees[], int &numberOfEmployees)
{
switch(menuChoice)
{
case 1:
{
//Open file in append mode
std::ifstream BinaryOpen("name.txt", std::ios::app | std::ios::binary);
//Open file in write mode
/*std::ofstream BinaryOpen("name.txt", std::ios::out | std::ios::binary);*/
//Check if file is open
if(BinaryOpen.is_open())
{
//Perform appropriate file operatings
std::cout << "\nFile opened! " << std::endl;
//Close file
BinaryOpen.close();
}
//Else
else
std::cout << "\nFile did not open! " << std::endl;
}
break;
case 2:
{
//Open file
std::ifstream BinaryOpen("employee.txt", std::ios::in /*| std::ios::out*/ | std::ios::binary);
//Check if file is open
if(BinaryOpen.is_open())
{
//Priming read
BinaryOpen >> favoriteEmployees[numberOfEmployees].firstName;
BinaryOpen >> favoriteEmployees[numberOfEmployees].lastName;
BinaryOpen >> favoriteEmployees[numberOfEmployees].hourlyWage;
BinaryOpen >> favoriteEmployees[numberOfEmployees].hoursWorked;
numberOfEmployees++;
//Read file
while(!BinaryOpen.eof())
{
BinaryOpen >> favoriteEmployees[numberOfEmployees].firstName;
BinaryOpen >> favoriteEmployees[numberOfEmployees].lastName;
BinaryOpen >> favoriteEmployees[numberOfEmployees].hourlyWage;
BinaryOpen >> favoriteEmployees[numberOfEmployees].hoursWorked;
numberOfEmployees++;
//Close file
BinaryOpen.close();
}
//Write to binary file
std::ofstream BinaryWrite("employee.dat", std::ios::out | std::ios::binary);
//Check if file opened
if(BinaryWrite.is_open())
{
BinaryWrite.write(reinterpret_cast <char *>(favoriteEmployees),
sizeof(Employee) * numberOfEmployees);
//Close file
BinaryWrite.close();
}
else
std::cout << "\nWrite file did not open! " << std::endl;
}
else
std::cout << "\nFile did not open! " << std::endl;
}
break;
case 3:
break;
case 4:
break;
default:
std::cout << "\nInvalid input. Please enter an integer from 1 to 4. " << std::endl;
}
}
**employee.h**
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
const int BUFFER_LENGTH = 20;
struct Employee
{
char firstName[BUFFER_LENGTH];
char lastName[BUFFER_LENGTH];
float hourlyWage;
float hoursWorked;
};
#endif
答案 0 :(得分:0)
这可能是一种不好的方法。就像Universe先生在评论中所说的那样,这些数组中包含所有那些没有数据的额外空白。我会将案例2代码改为更像以下内容:
//#include <iomanip> for the stream formatting used when printing to the file
case 2:
{
//Open file
std::ifstream BinaryOpen("employee.txt", std::ios::in /*| std::ios::out*/ | std::ios::binary);
//Check if file is open
if(BinaryOpen.is_open())
{
//Read file
char eol[10];
while(BinaryOpen.good())
{
BinaryOpen >> favoriteEmployees[numberOfEmployees].firstName;
BinaryOpen >> favoriteEmployees[numberOfEmployees].lastName;
BinaryOpen >> favoriteEmployees[numberOfEmployees].hourlyWage;
BinaryOpen >> favoriteEmployees[numberOfEmployees].hoursWorked;
BinaryOpen >> eol;
numberOfEmployees++;
}
//Close file
BinaryOpen.close();
//Write to binary file
std::ofstream BinaryWrite("employee.dat", std::ios::out | std::ios::binary);
//Check if file opened
if(BinaryWrite.is_open())
{
for (int i = 0; i < numberOfEmployees; i++)
{
BinaryWrite << favoriteEmployees[i].firstName << " ";
BinaryWrite << favoriteEmployees[i].lastName << " ";
BinaryWrite << setiosflags(std::ios::fixed) << std::setprecision(2) << favoriteEmployees[i].hourlyWage << " ";
BinaryWrite << setiosflags(std::ios::fixed) << std::setprecision(2) << favoriteEmployees[i].hoursWorked << std::endl;
}
//Close file
BinaryWrite.close();
}
else
std::cout << "\nWrite file did not open! " << std::endl;
}
else
std::cout << "\nFile did not open! " << std::endl;
}
break;
答案 1 :(得分:0)
正如我上面的评论。我已经掀起了一个快速的例子,它会让你知道如何做到这一点。
void SaveString(fstream& file_stream, string output)
{
// Note that any good string class will have an implicit conversion to char*
if (output.size() == 0)
return;
file_stream << (unsigned char)output.size();
for (unsigned char i=0; i<output.size(); i++)
file_stream << output[i];
// DONE (in theory)
}
然后你需要做的就是在字符串的开头获取1个unsigned char,然后在for循环中使用该数字来获取字符并将它们添加到你加载的字符串中。
答案 2 :(得分:0)
这就是它打印垃圾的原因:
BinaryWrite.write(reinterpret_cast <char *>(favoriteEmployees),
sizeof(Employee) * numberOfEmployees);
那些可能不是你看到的空格,但是是NULL字符或其他unprintables。
您需要做的是编写文件字段:
BinaryWrite << favoriteEmployees[i].firstName << " ";
BinaryWrite << favoriteEmployees[i].lastName << " ";
BinaryWrite << std::setprecision(2) << favoriteEmployees[i].hourlyWage << " ";
BinaryWrite << std::setprecision(2) << favoriteEmployees[i].hoursWorked << std::endl;
调用这些二进制文件可能有点误导,因为它们实际上只包含文本。实际的二进制文件将包含固定长度,长度前缀或零终止的字符串,以及数字的二进制表示(您无意中在原始代码中执行了这些操作)。