从文件中读取数据并将其存储到结构中 我是C++初学者,在从输入文件中读取数据块时,在输出文件中正确显示数据是有困难的。我需要使用的输入文件中的文本如下所示:
&仓库 输出应如下所示: Id:(某个整数) 部门:仓库 小时数:(部分浮动) 以下是我到目前为止的情况:从文件中读取数据并将其存储到结构中 我是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
#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分钟来更新自己,然后才能开始使用……)