fread 正在读取文件中的垃圾

fread is reading garbage in file

我正在做作业,遇到了 C++ 中的 fread() 问题。当我修改我的文件中的名称时,它会根据我的需要完美地修改它,但是当我之后尝试读取文件时出现问题,它读取整个文件但它不会停止,总共 运行 146 次而只有 3 个名字。

我的代码:-

#include <bits/stdc++.h>
using namespace std;

struct person{
    int id; 
    string fname; 

}s;

void write(){
    FILE *outfile;
    struct person input; 
    int num,ident;
    string sname[] = {"a","b","c"};

    outfile = fopen ("C:\Users\Amritesh\Desktop\students.txt","wb");

    if (outfile == NULL) 
    { 
        fprintf(stderr, "\nError opend file\n"); 
        exit (1); 
    } 

    scanf("%d",&num);

    for(int i=0;i<num;i++){

        s.fname = sname[i];
        cin >> s.id;

        fwrite (&s, sizeof(s), 1, outfile);
    }
    fclose(outfile);
}

void read(){

    FILE *file1;
    int i=0;
    file1 = fopen ("C:\Users\Amritesh\Desktop\students.txt","r");

    while(fread(&s, sizeof(s), 1, file1) == 1) {    

        cout << "ID " << s.id << "  Name " <<s.fname << endl;
    }

    fclose (file1); 


} 

void modify(){
    FILE *file;
    file = fopen ("C:\Users\Amritesh\Desktop\students.txt","r+");

    while(fread(&s, sizeof(s), 1, file)) {

        if(s.fname == "a"){
            s.fname = "d";
            fseek(file,-sizeof(s),SEEK_CUR);
            fwrite (&s, sizeof(s), 1,file);
        }
    }

    fclose (file); 
}

int main(){
    write();
    modify();
    read();
}

编辑代码:-

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

struct person 
{ 
    int id; 
    string fname; 
}s,temp; 



void read() 
{ 
    int num;
    
    ifstream fin;
    fin.open("C:\Users\Amritesh\Desktop\student.txt",ios::in);
    fin.seekg(0,ios::beg);
    

    //scanf("%d",&num);

    while(fin){

        cout << s.fname << s.id << endl;
    }

    fin.close();
}

void write(){

    int i=0;
    ofstream fout;

    fout.open("C:\Users\Amritesh\Desktop\student.txt");
    
    
    while(i!=2) {   
        cin >> s.id >> s.fname;
        fout << "ID " << s.id << "  Name " <<s.fname << endl;
        i++;
    }

    
    fout.close();
    
} 

void modify(){

    fstream mod;
    mod.open ("C:\Users\Amritesh\Desktop\student.txt");
    
    while(mod) {

        if(s.fname == "a"){
            s.fname = "d";
            mod.seekg(-sizeof(s),ios::cur);
            mod << s.fname;
        }
    }

    
    mod.close();
}

int main(){
    
    write();
    read();
    modify();
    
}

感谢您的回答!

以下是基于我们讨论的三个想法。我将从读取和写入 person 对象的免费函数开始,因为看起来您现在正处于那个阶段。我将继续在您的 person class 中添加成员函数,最后添加流运算符以方便使用。

免费 (non-member) readwrite 函数的示例:

#include <iostream>
#include <string>
#include <fstream>

struct person {
    int id; 
    std::string fname; 
};

std::ostream& write(std::ostream& os, const person& p) {
    os << p.id << ',' << p.fname << '\n'; // stream out the properties of a person
    return os; // look at the next example for an alternative doing the same thing
}

std::istream& read(std::istream& is, person& p) {
    // extract "id" and if it succeeds, check if the next char is a , char
    if(is >> p.id && is.peek() == ',') { 
        is.ignore();               // step over the , char
        std::getline(is, p.fname); // read the rest of the line into p.fname
    } else {
        // we didn't get id or the , char, so set the stream in a failed state
        is.setstate(is.failbit);       
    }
    return is;
}

int main() {
    // write to file
    {
        std::ofstream file("C:\Users\Amritesh\Desktop\student.txt");
        person test1{10, "Foo Bar"};
        person test2{20, "Apa Bepa"};
        write(file, test1);
        write(file, test2);
    }
    // read from file
    {
        std::ifstream file("C:\Users\Amritesh\Desktop\student.txt");
        person test;

        while(read(file, test)) {
            std::cout << test.fname << '\n';
        }
    }
}

person中创建readwrite成员函数的例子:

#include <iostream>
#include <string>
#include <fstream>

struct person {
    int id; 
    std::string fname;

    std::ostream& write(std::ostream& os) const {
        // this does the same thing as in the first example
        return os << id << ',' << fname << '\n';        
    }

    std::istream& read(std::istream& is) {
        if(is >> id && is.peek() == ',') {
            is.ignore(); // step over the , char
            std::getline(is, fname);
        } else {
            is.setstate(is.failbit); // we didn't get id or the , char
        }
        return is;
    }    
};

int main() {
    // write to file
    {
        std::ofstream file("C:\Users\Amritesh\Desktop\student.txt");
        person test1{10, "Foo Bar"};
        person test2{20, "Apa Bepa"};
        test1.write(file);
        test2.write(file);
    }
    // read from file
    {
        std::ifstream file("C:\Users\Amritesh\Desktop\student.txt");
        person test;

        while(test.read(file)) {
            std::cout << test.fname << '\n';
        }
    }
}

流操作符支持的成员函数:

#include <iostream>
#include <string>
#include <fstream>

struct person {
    int id; 
    std::string fname;

    std::ostream& write(std::ostream& os) const {
        return os << id << ',' << fname << '\n';        
    }

    std::istream& read(std::istream& is) {
        if(is >> id && is.peek() == ',') {
            is.ignore(); // step over the , char
            std::getline(is, fname);
        } else {
            is.setstate(is.failbit); // we didn't get id or the , char
        }
        return is;
    }    
};

// stream operators calling member functions
std::ostream& operator<<(std::ostream& os, const person& p) { return p.write(os); }
std::istream& operator>>(std::istream& is, person& p) { return p.read(is); }

int main() {
    // write to file
    {
        std::ofstream file("C:\Users\Amritesh\Desktop\student.txt");
        person test1{10, "Foo Bar"};
        person test2{20, "Apa Bepa"};
        file << test1 << test2;  // calling operator<< for each person object
    }
    // read from file
    {
        std::ifstream file("C:\Users\Amritesh\Desktop\student.txt");
        person test;

        while(file >> test) {    // extract one person at a time using operator>>
            std::cout << test.fname << '\n';
        }
    }
}