简体   繁体   中英

Reading data from a file and storing it into a structure

I'm a beginner to C++ and I'm having trouble reading blocks of data from an input file and displaying that data properly in an output file. The text inside the input file I need to use looks like this:

& Warehouse ÿÿÿÿ X¦a¤ Ãq¹B

The output should look something like this:

Id: (some integer)

Department: Warehouse

Hours: (some float)

Heres what I have so far:

#include<iostream>
#<include<fstream>
#include<string>
using namespace std;

struct employee {
   int id;
   char department[25];
   float hours;
};

int main()
{
   ifstream inputFile;
   ofstream outputFile;
   string inFilename, outFileName;

   cout << "Please give me two file names" << endl;
   getline(cin, inFileName);
   getline(cin, outFileName);


   inputFile.open(inFileName);
   outputFile.open(outFileName);

   if (inputFile.eof())
   {
      inputFile.close();
      outputFile.close();
   }
   string buffer;
   employee emp;
   inputFile.read(reinterpret_cast<char*>(&emp), sizeof(emp));
   while (!inputFile.eof())
   {

      outputFile << "Id:\t" << emp.id << endl;
      outputFile << "Department:\t" << emp.department << endl;
      outputFile << "Hours:\t" << emp.hours << endl;
      inputFile.read(reinterpret_cast<char*>(&emp), sizeof(emp));
   }

   inputFile.close();
   outputFile.close();

   return 0;
}

My output looks like this:

Id: 538968358

Department: Warehouse ÿÿÿÿ X¦a¤ Ãq¹BÌÌÌÌÌÌÌÌ î

Hours: 92.7222

Why is it still outputting these strange characters on the department line? Im having a hard time understanding what exactly the read function is doing when I call it and I think this might be whats causing the issue. I've looked into what the read function does but I couldn't find anything that could explain what was happening in this context specifically with the reinterpret cast. I know it takes two parameters, the first one being "char*" but in this case we are using the reinterpret cast to take the characters and turn them into type employee defined by the structure. The second parameter is sizeof and thats supposed to indicate how many characters its reading from the file I think? If I knew exactly how the read() function was working in this context I could probably figure out why its outputting the strange characters.

In c++ the char[] must include a \\0 charater for indicate the end of the text. otherwise unspected resuts because qye data of the array is not initialized to any values and contains arbitrary characters. When you try to output the char[25] departament, if after 'warehouse' dont have a \\0 char then output all 25 chars.

You are actually fairly close. Your primary stumbling block comes from failing to open inputFile in binary mode (eg specifying mode as ios::binary ). Your secondary issues have to do with validation. All input must be validated (especially user input). All file openings must be validated (and you should validate a close after a write. by checking if failbit indicates a stream error following close. note this is only necessary after a write )

Putting those pieces together (and leaving the check of failbit after close of outputFile to you), it looks like you intended something similar to the following:

#include<iostream>
#include<fstream>
#include<string>
using namespace std;

struct employee {
    int id;
    char department[25];
    float hours;
};

int main()
{
    ifstream inputFile;
    ofstream outputFile;
    string inFilename, outFilename, buffer;
    struct employee emp;

    cout << "Please give me two file names" << endl;
    /* validate all input succeeds */
    if (!getline (cin, inFilename)) {
        cerr << "error: invalid input for input file.\n";
        return 1;
    }
    if (!getline (cin, outFilename)) {
        cerr << "error: invalid input for output file.\n";
        return 1;
    }

    /* open file in binary mode 'ios::binary' */
    inputFile.open (inFilename, ios::binary);

    /* valdiate all files open for reading/writing */
    if (!inputFile.is_open()) {
        perror (("error opening: " + inFilename).c_str());
        return 1;
    }
    outputFile.open (outFilename);
    if (!outputFile.is_open()) {
        perror (("error opening: " + outFilename).c_str());
        return 1;
    }

    /* while each read succeeds, write to output file */
    while (inputFile.read (reinterpret_cast<char*>(&emp), sizeof(emp)))
    {
        outputFile << "Id:\t" << emp.id << endl;
        outputFile << "Department:\t" << emp.department << endl;
        outputFile << "Hours:\t" << emp.hours << endl;
    }

    inputFile.close();  /* close files */
    outputFile.close();

    return 0;
}

Example output data1.info

$ ./bin/read_binary_info
Please give me two file names
dat/data1.info
dat/data1.txt

$ cat dat/data1.txt
Id:     579
Department:     Warehouse
Hours:  95.9083
Id:     23
Department:     Admin
Hours:  33.7954
Id:     901
Department:     Operations
Hours:  99.5081
Id:     193
Department:     Admin
Hours:  2.15763
...
Id:     707
Department:     Maintenance
Hours:  63.801
Id:     110
Department:     Sales
Hours:  1.22974

Example outoput data3.info

$ ./bin/read_binary_info
Please give me two file names
dat/data3.info
dat/data3.txt

$ cat dat/data3.txt
Id:     294
Department:     Warehouse
Hours:  92.7222

Look things over and let me know if you have further questions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM