从文件中读取数据并将其存储到结构中

时间:2018-03-10 00:53:26

标签: c++ visual-studio-2017

我是C ++的初学者,我无法从输入文件中读取数据块并在输出文件中正确显示数据。我需要使用的输入文件中的文本如下所示:

&安培;仓库ÿÿÿÿX |a¤Ãq¹B

输出应该如下所示:

Id :(某个整数)

部门:仓库

小时:(有些漂浮)

到目前为止我所拥有的:

#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;
}

我的输出如下:

Id:538968358

部门:仓库ÿÿÿÿX |a¤Ãq¹BÌÌÌÌÌ

时间:92.7222

为什么它仍然在部门线上输出这些奇怪的字符? 我很难理解当我调用它时读取函数究竟是做什么的,我认为这可能是导致问题的原因。我已经研究了read函数的作用但是我找不到任何可以解释在这个上下文中发生的事情,特别是重新解释转换。我知道它需要两个参数,第一个是“char *”,但在这种情况下,我们使用重新解释转换来获取字符并将它们转换为结构定义的类型雇员。第二个参数是sizeof,那应该表明我从文件中读取了多少个字符?如果我确切地知道read()函数在这个上下文中是如何工作的,我可能会弄清楚它输出奇怪字符的原因。

2 个答案:

答案 0 :(得分:0)

在c ++中,char []必须包含一个\ 0字符,用于指示文本的结尾。 因为数组的qye数据没有初始化为任何值并包含任意字符,否则未经预期的resuts。 当您尝试输出char [25]部分时,如果在&#39;仓库&#39;之后没有\ 0字符然后输出所有25个字符。

答案 1 :(得分:0)

你实际上相当接近。您的主要障碍来自于无法以二进制模式打开inputFile(例如,将mode指定为ios::binary)。您的次要问题与验证有关。必须验证所有输入(尤其是用户输入)。必须验证所有文件打开(并且您应该在写入后验证关闭。通过检查关闭后failbit是否指示流错误。 note 仅在写入后才需要这样做

将这些部分组合在一起(并在failbit关闭之后将outputFile的检查留给您),看起来您的意图类似于以下内容:

#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;
}

示例输出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

示例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

仔细看看,如果您有其他问题,请告诉我。