C++ 如何编写C++;仅使用标准库将对象复制到文件
首先,我要澄清是什么让这个问题不会被愚弄:C++ 如何编写C++;仅使用标准库将对象复制到文件,c++,C++,首先,我要澄清是什么让这个问题不会被愚弄: < >禁止在标准C++库之外的任何内容,即 包括boost和其他库 对象可能包含malloc-ed C样式数组 在将此问题标记为重复之前,请提供一个问题,说明这两个要求在哪里得到解决 在标记这个问题没有用之前,请考虑编写不良数据成员的对象可能是我即将在大学进行C++测试的合法要求。我在前几年看过一些测试,其中指出一个类BankAccount必须有2个动态分配的double*。至于为什么只使用标准库,恐怕很可能我们的老师不知道如何使用boost,或者
-
< >禁止在标准C++库之外的任何内容,即
包括boost和其他库
- 对象可能包含
-ed C样式数组malloc
BankAccount
必须有2个动态分配的double*
。至于为什么只使用标准库,恐怕很可能我们的老师不知道如何使用boost,或者除了std以外的任何东西
我尝试过这段代码,但不幸的是,这段代码不太正确:
#include<fstream>
#include<iostream>
using namespace std;
class Student
{
int roll;
char name[25];
float marks;
int *arr;
double *second;
public:
friend ostream& operator<<(ostream& out, const Student &s)
{
out << s.marks << s.name << s.roll;
for (int i = 0; i < 5; ++i) {
out << s.arr[i];
}
for (int i = 0; i < 10; ++i) {
out << s.second[i];
}
out << std::endl;
return out;
}
friend istream& operator>>(istream& ins, Student &s)
{
ins >> s.marks >> s.name >> s.roll;
for (int i = 0; i < 5; ++i) {
ins >> s.arr[i];
}
for (int i = 0; i < 10; ++i) {
ins >> s.second[i];
}
return ins;
}
Student() : roll(10), name("Platon"), marks(4)
{
arr = new int[5];
second = new double[10];
for (int i = 0; i < 5; ++i) {
arr[i] = i + 1;
}
for (int j = 0; j < 10; ++j) {
second[j] = j + 1;
}
}
Student(int r, char n[25], float m, int* a, double* s): roll(r), marks(m)
{
arr = new int[5], second = new double[10];
for (int i = 0; i < 25; ++i) {
name[i] = n[i];
}
for (int j = 0; j < 5; ++j) {
arr[j] = a[j];
}
for (int k = 0; k < 10; ++k) {
second[k] = s[k];
}
}
};
int main()
{
int dummy[] = {1, 2, 3, 4, 5};
double another[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
ofstream fp("file.bin", ofstream::out|ofstream::binary);
Student S(56, "Platon Makovsky", 14.2, dummy, another);
cout << "writing: "; cout << S << std::endl;
fp << S;
fp.close();
Student test;
ifstream f("file.bin", ifstream::in|ifstream::binary);
f >> test;
cout << "read: "; cout << test << std::endl;
f.close();
return 0;
}
由于某种原因,程序无法读取完整的名称和卷。对此问题的任何帮助都将不胜感激
顺便说一句,我知道
使用名称空间std代码>,我只是不想一直写std::
。为了简洁起见省略了析构函数,我也知道内存管理。好的,有一些原因可以解释为什么会有XML和JSON等文件格式的正式定义。你打到了
您需要一些方法来确定各个字段的开始和结束位置。例如,假设您决定将每个字段放在自己的行上。这是完全合法的。将它们写出来,每行一行,当您读回它们时,从文件中读取行并转换为正确的数据类型。简单
直到你拿出一个带换行符的字符串。现在这个值跨越了两条线,这可能是你没有考虑过的。
因此,我将编写一个函数,将字符串转换为“安全字符串”。具体来说,请将换行符的每个实例转换为字符\n。同时,将一个\转换为两个\。想象一下这个字符串:
This is foo\bar.
And it had a newline.
这将变成:
This is foo\\bar.\nAnd it had a newline.
(字面上——这不是新行,这是一种可以识别为新行的字符串表示形式。)
然后编写反向函数。它将\转换为单个\并\n再次转换为正确的换行符
这是第一步
第二步:决定如何指示字段为空。你可以直接写空。这适用于数字字段,但如果这样做,您将如何处理空字符?您仍然可以写入null,但是如果您的值实际上是文本null呢?决定您希望如何表示这一点。您可以让指针类似于“value=12345”或“value=abcde”,然后null可以只是“null”。那是安全的
第三步:写下你的字段,每行一个。在编写字符串时使用此安全字符串方法,并对指针执行任何操作
第四步:编写一个方法,一次读取一行文件,然后打印出来(这样你就知道它是有效的)
第五步:使用它生成新对象(从文件中读取)
如果操作正确,您应该能够处理所有基本数据类型
这可能需要一两个小时。您可以使用std::cout列出名称空间的所有元素,如;使用std::ofstream
。没有理由使用std::endl
。您可以使用'\n'
。如果允许使用stl,为什么不使用std::string
而不是char数组?std::array
,std::vector
和std::unique\u ptr
是标准库中的元素,您应该阅读有关ins>>s.marks>>s.name>>s.roll的内容代码>:s.marks
获取14.2
s.name
获取Platon
。(然后,>
由于空格而停止格式化输入。)猜猜看,s.roll
得到了什么。(流进入错误状态。)写入不是问题。读数是。您必须使用一个可以由两者明确确定的分隔符。您可以使用例如\n
或其他既不是数字的一部分也不是名称的东西(例如;
)。然后,查找std::getline()
,您可以通过代码定义分隔符。
This is foo\\bar.\nAnd it had a newline.