C++ 从文件读取时获取垃圾字符

C++ 从文件读取时获取垃圾字符,c++,C++,我有一个CS项目,我正在尝试将字符串写入/读取到一个string变量中,比如大小为10的x。我对编码还不熟悉,我在写文件时犯了一些错误。请帮帮我 下面是我在项目文件中定义的类,它包括我的字符串x[10]数组。我很确定我在写入文件时犯了一个错误,因为它在文件中添加了垃圾字符 void write_announcement() { student st; string line; int num; ofstream file; file.

我有一个CS项目,我正在尝试将字符串写入/读取到一个
string
变量中,比如大小为10的
x
。我对编码还不熟悉,我在写文件时犯了一些错误。请帮帮我

下面是我在项目文件中定义的类,它包括我的
字符串x[10]
数组。我很确定我在写入文件时犯了一个错误,因为它在文件中添加了垃圾字符

void write_announcement()
{
    student st;          
    string line;
    int num;

    ofstream file;
    file.open("announcement.txt");

    cout << "Enter number:";
    cin >> num;

    cin.ignore();
    getline(cin,line);

    announce[num] = line;
    file.write(reinterpret_cast<char *> (&st), sizeof(student));

    file.close();
}    

void read_announcement()
{
    student st;
    int n;
    cout << "Enter n: ";
    cin >> n;

    ifstream file;
    file.open("announcement.txt");

    while (file >> st.announce[n]);
    {
       cout << announce[n];
    }

    file.close();
}
void write_公告()
{
学生会;
弦线;
int-num;
流文件;
打开(“announcement.txt”);
cout>num;
cin.ignore();
getline(cin,line);
宣布[num]=行;
write(reinterpret_cast(&st),sizeof(student));
file.close();
}    
无效读_公告()
{
学生会;
int n;
cout>n;
ifstream文件;
打开(“announcement.txt”);
while(文件>>st.announce[n]);
{

cout您不能像流那样写入/读取
std::string
对象,更不用说字符串数组了。您正在写入/读取每个字符串的内部数据,其中包括一个指向存储在内存中其他位置的字符数据的指针,可能是一个用于短字符串优化的小缓冲区您正在写入/读取的是内部数据,而不是实际的字符数据。这就是为什么您的文件中会出现“垃圾”的原因

写入时,需要将字符串数据序列化为一种格式,以便在读回时进行反序列化,例如:

struct student
{
    string announce[10];
};

ostream& operator<<(ostream &os, const student &st)
{
    for(int x = 0; x < 10; ++x)
        os << st.announce[x] << '\n';
    return os;
}

istream& operator>>(istream &is, student &st)
{
    for(int x = 0; x < 10; ++x)
        getline(is, st.announce[x]);
    return is;
}

void write_announcement()
{
    student st;
    string line;
    int num;

    cout << "Enter number: ";
    cin >> num;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    if ((num < 0) || (num >= 10))
    {
        cout << "Invalid number!" << endl;
        return;
    }

    cout << "Enter text: ";
    getline(cin, line);

    st.announce[num] = line;

    ofstream file("announcement.txt");
    if (!file.is_open())
    {
        cout << "Cannot create file!" << endl;
        return;
    } 

    if (!(file << st))
    {
        cout << "Cannot write to file!" << endl;
    }
}

void read_announcement()
{
    student st;
    int num;

    cout << "Enter number: ";
    cin >> num;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    if ((num < 0) || (num >= 10))
    {
        cout << "Invalid number!" << endl;
        return;
    }

    ifstream file("announcement.txt");
    if (!file.is_open())
    {
        cout << "Cannot open file!" << endl;
        return;
    }

    if (!(file >> st))
    {
        cout << "Cannot read from file!" << endl;
        return;
    }

    cout << "Text: " << st.announce[num] << endl;
}
struct学生
{
字符串公告[10];
};
ostream(操作员=10))
{

cout What is announce?st.announce?欢迎来到Stack Overflow。请花点时间浏览并参考中关于您可以在此处询问的内容和方式的资料。发布一篇文章尤为重要。这并不能解决问题,但要养成用有意义的值初始化对象的习惯,而不是创建对象并立即进行指定一个值。也就是说,将
ifstream文件;file.open(“announcement.txt”);
更改为
ifstream文件(“announcement.txt”);
。您不需要调用
file.close()
。析构函数将执行此操作。顺便说一句,您不能将
std::string
作为二进制文件写入文件。
std::string
包含指针,指针将随程序的每次实例化而改变。您必须先写入长度,然后是文本,或者先写入文本,然后是nul,
'\0'
字符。Remy Lebeau我仍然无法使用您为我编写的代码在文件中写入。请您再努力一点,这样我就可以完成。请!各位宣布我正在使用的字符串数组,很抱歉我在写问题时提到了x。@MuhammadNoman“我仍然无法在文件中写入”-为什么不?你到底在哪里失败了?我添加了错误检查,你缺少。输出是什么?请更具体一点。“你能再努力一点吗?”-对不起?到目前为止,我已经在我发布的内容上投入了很多精力。你为什么不花更多精力学习如何调试你自己的代码?这是一项必须具备的基本技能。StackOverflow不是一项调试服务,也不是一项代码编写服务,所以不要把它当作一项服务。好吧,谢谢你的帮助。我对progra非常陌生mming,我的老师给我们的项目太早了。他没有教我们足够多。很抱歉给我们带来不便。顺便说一句,我已经修复了你给我的代码中的一个错误。它要求我写文本,但没有存储到文件中。实际上,很抱歉,它要求输入文本,但它将新输入的文本存储到文件中,并删除以前的文本one@MuhammadNoma是有意义的,因为您每次写入/读取文件时都要创建一个新的本地
学生
,但每次写入时只填充一个字符串,并且不会在多次写入时保留以前的字符串。因此,1)在写入新字符串之前读取文件以加载以前的字符串,或2)使
学生
成为全局变量能够的
struct student
{
    string announce[10];
};

ostream& operator<<(ostream &os, const student &st)
{
    for(int x = 0; x < 10; ++x)
    {
        uint32_t len = st.announce[x].size();
        os.write(reinterpret_cast<char*>(&len), sizeof(len));
        os.write(st.announce[x].c_str(), len);
    }
    return os;
}

istream& operator>>(istream &is, student &st)
{
    for(int x = 0; x < 10; ++x)
        st.announce[x].clear();

    for(int x = 0; x < 10; ++x)
    {
        uint32_t len;
        if (!is.read(reinterpret_cast<char*>(&len), sizeof(len))) break;
        string s;
        if (len > 0)
        {
            s.resize(len);
            if (!is.read(&s[0], len)) break;
        }
        st.announce[x] = s;
    }

    return is;
}

void write_announcement()
{
    student st;
    string line;
    int num;

    cout << "Enter number: ";
    cin >> num;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    if ((num < 0) || (num >= 10))
    {
        cout << "Invalid number!" << endl;
        return;
    }

    cout << "Enter text: ";
    getline(cin, line);

    st.announce[num] = line;

    ofstream file("announcement.txt", ofstream::binary);
    if (!file.is_open())
    {
        cout << "Cannot create file!" << endl;
        return;
    } 

    if (!(file << st))
    {
        cout << "Cannot write to file!" << endl;
    }
}

void read_announcement()
{
    student st;
    int num;

    cout << "Enter number: ";
    cin >> num;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    if ((num < 0) || (num >= 10))
    {
        cout << "Invalid number!" << endl;
        return;
    }

    ifstream file("announcement.txt", ifstream::binary);
    if (!file.is_open())
    {
        cout << "Cannot open file!" << endl;
        return;
    }

    if (!(file >> st))
    {
        cout << "Cannot read from file!" << endl;
        return;
    }

    cout << "Text: " << st.announce[num] << endl;
}