从文件中读取数据并将其存储到结构中 我是C++初学者,在从输入文件中读取数据块时,在输出文件中正确显示数据是有困难的。我需要使用的输入文件中的文本如下所示:

从文件中读取数据并将其存储到结构中 我是C++初学者,在从输入文件中读取数据块时,在输出文件中正确显示数据是有困难的。我需要使用的输入文件中的文本如下所示:,c++,visual-studio-2017,C++,Visual Studio 2017,&仓库 输出应如下所示: Id:(某个整数) 部门:仓库 小时数:(部分浮动) 以下是我到目前为止的情况: #include<iostream> #<include<fstream> #include<string> using namespace std; struct employee { int id; char department[25]; float hours; }; int main() { ifstream

&仓库

输出应如下所示:

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

在C++中,char []必须包含一个0字符来指示文本的结尾。 否则会出现未预期的结果,因为数组的qye数据未初始化为任何值,并且包含任意字符。
当您尝试输出char[25]department时,如果'warehouse'后面没有\0 char,则输出所有25 char。

实际上您已经非常接近了。您的主要障碍来自未能在二进制模式下打开
inputFile
(例如,将
mode
指定为
ios::binary
)。您的次要问题与验证有关。必须验证所有输入(尤其是用户输入)。必须验证所有打开的文件(并且您应该在写入后验证关闭。通过检查
failbit
是否指示关闭后的流错误。注意,这仅在写入后才有必要)

将这些部分放在一起(并在关闭
outputFile
后将检查
failbit
留给您),看起来您打算做如下类似的事情:

#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;
}
示例输出数据3.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
$ ./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

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

department
成员变量可以容纳25个字符,因此
read
命令将其填满。如果您想要更细致的阅读,比如读到一个空格(“”),那么您必须编写更细致的代码。我建议避免使用字符串(
char[]
),并坚持使用简单的类型,如
int
double
,直到您很好地掌握了二进制I/O问题。“输入文件中的文本”——它甚至是文本文件,还是二进制文件。
是一个.info文件,我怀疑它是二进制的。您是否获得了要读取的字节数,或者文件的格式,以便您创建一个输入例程来读取文件?你必须知道二进制文件中的内容才能知道如何读取它。(例如,前8个字节的
double
,后4个字节的
int
,等等)它是应该满是
struct employee
,还是前面有一个
int
告诉您有多少人。还记得吗,如果
.info
文件不是写在windoze上的,那么由于编译器之间的结构填充不同,无法保证您可以读取它。请发布一个链接到您的
.info
文件,或者如果它只有大约100个字节,发布一个hextump。进行了验证更改,并以二进制文件的形式打开了输入文件,但我仍然在输出中得到奇怪的字符。我把文件保存在哪里重要吗?不应该,但你如何保存可能重要。我刚转到你的链接,点击“保存”。中间没有应用程序(除了浏览器)。请注意,我是如何更改您的读取循环(while
)以消除内部
.feof
和末尾的读取的。虽然这只会影响最后一个结构(如果有),但这不应该是问题的原因。你知道
.info
文件最初是不是在Linux机器上用
gcc
而不是VS创建的吗?正如我在对你的问题的评论中提到的那样,这可能会对内部结构填充产生影响。我在Win7上的VS 10上编译过(32位),两个文件都读得很好,因此填充似乎不是问题。VS 10和gcc对填充物的处理是相同的。(如果是4字节对齐,则每个员工36字节,如果是8字节对齐,则每个员工40字节。我会做一个快速检查,但我已经检查过了。在64位Linux和32位Win7上,我都会得到
sizeof emp
作为
36字节
。我会启动64位win 10并尝试一下。如果您尝试过我发布的代码,填充是最重要的。)唯一能起作用的是。@Will-i-am我现在已经在VS 2017(32位和64位版本)上确认数据文件读起来很好。(我本来可以更早完成,但就像任何几周内没有启动的windoze一样,它必须花10分钟来更新自己,然后才能开始使用……)