c++ - 写入二进制文件时空格过多

标签 c++ struct binaryfiles

尝试从结构写入二进制文件。不幸的是,它写出了过多的空格,因为我的字符串都是 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

最佳答案

这就是它打印垃圾的原因:

BinaryWrite.write(reinterpret_cast <char *>(favoriteEmployees),
    sizeof(Employee) * numberOfEmployees);

您看到的可能不是空格,而是 NULL 字符或其他不可打印的字符。

您需要做的是编写文件字段:

BinaryWrite << favoriteEmployees[i].firstName << " ";
BinaryWrite << favoriteEmployees[i].lastName << " ";
BinaryWrite << std::setprecision(2) << favoriteEmployees[i].hourlyWage << " ";
BinaryWrite << std::setprecision(2) << favoriteEmployees[i].hoursWorked << std::endl;

调用这些二进制文件可能有点误导,因为它们实际上只包含文本。实际的二进制文件将包含固定长度、长度前缀或零终止的字符串,以及数字的二进制表示(您在原始代码中无意中这样做了)。

关于c++ - 写入二进制文件时空格过多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15148721/

相关文章:

c++ - 使用 union 从 double 转换为十六进制再转换为 double

c++ - 输出无序映射中的结构变量

reverse-engineering - 如何为 Elden Ring 保存文件创建数据表

c - 这个半反编译代码有什么作用(C)

nexus - Nexus 存储库是否重复在不同存储库中提供帮助并具有相同摘要的二进制文件?

C++ 循环依赖

c++ - 我可以在 STL 中禁用异常吗?

c - 难以将结构传递给函数

c - 将两个别名传递给 `typedef struct` 意味着什么?

c++ - C++ 中逗号分隔值的 `operator<<`