Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何编写C++;仅使用标准库将对象复制到文件_C++ - Fatal编程技术网

C++ 如何编写C++;仅使用标准库将对象复制到文件

C++ 如何编写C++;仅使用标准库将对象复制到文件,c++,C++,首先,我要澄清是什么让这个问题不会被愚弄: < >禁止在标准C++库之外的任何内容,即 包括boost和其他库 对象可能包含malloc-ed C样式数组 在将此问题标记为重复之前,请提供一个问题,说明这两个要求在哪里得到解决 在标记这个问题没有用之前,请考虑编写不良数据成员的对象可能是我即将在大学进行C++测试的合法要求。我在前几年看过一些测试,其中指出一个类BankAccount必须有2个动态分配的double*。至于为什么只使用标准库,恐怕很可能我们的老师不知道如何使用boost,或者

首先,我要澄清是什么让这个问题不会被愚弄:

    < >禁止在标准C++库之外的任何内容,即 包括boost和其他库
  • 对象可能包含
    malloc
    -ed C样式数组
在将此问题标记为重复之前,请提供一个问题,说明这两个要求在哪里得到解决

<>在标记这个问题没有用之前,请考虑编写不良数据成员的对象可能是我即将在大学进行C++测试的合法要求。我在前几年看过一些测试,其中指出一个类
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.