1

構造体からバイナリ ファイルを書き込もうとしています。残念ながら、私の文字列はすべて 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;
}

プロトコル.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

プロトコル.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
4

3 に答える 3

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)
}

次に、getで行う必要があるのは、文字列の先頭で1つのunsigned charを取得し、その数値をforループで使用して、charを取得し、ロード先の文字列に追加することです。

于 2013-03-01T02:35:14.107 に答える
0

これがゴミを印刷している理由です:

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;

これらのファイルには実際にはテキストしか含まれていないため、これらをバイナリ ファイルと呼ぶのは少し誤解を招く可能性があります。実際のバイナリ ファイルには、固定長、長さのプレフィックスまたは 0 で終了する文字列、および数値のバイナリ表現が含まれます (元のコードで誤って実行してしまいました)。

于 2013-03-01T02:39:13.280 に答える
0

それはおそらくこれを行う悪い方法です。ユニバース氏がコメントで言っていたように、これらの配列には、データのない追加の空白がすべて含まれています。ケース 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;
于 2013-03-01T02:32:19.027 に答える