В каком режиме открывается файл, чтобы seekp () работал так же, как в файле, открытом в режиме по умолчанию? - PullRequest
0 голосов
/ 27 апреля 2019

Я написал следующий код на C ++, который записывает объект Student в файл, а затем использовал seekp () для перемещения выходного указателя в определенную позицию, где я написал объект Student, который заменил предыдущий объект в этой позиции, оставив другиебез изменений.

Чтобы получить тот же результат, в каком режиме я должен открыть файл, где выполняется seekp ()?(Как прокомментировано)

#include<iostream>
#include<string.h>
#include<fstream>
using namespace std;
class Student{
    private:
    int roll;
    char name[30];
    int marks;
    public:
    Student(int roll=0, char const nameData[]="", int marks=0){
        this->roll=roll;
        strcpy(name,nameData);
        this->marks=marks;
    }
    void print(){
        cout<<"Student Name : "<<name<<endl;
        cout<<"Student Roll No : "<<roll<<endl;
        cout<<"Student's Score : "<<marks<<endl;
    }
};
int main(){
    Student s1(25,"D Dhar",85);
    Student s2(28, "A Sinha ",45);
    Student s3(29, "B Sinha ",49);
    Student s4(45, "C Sinha ",96);
    Student s5(47, "D Sinha ",23);
    s1.print();
    s2.print();
    s3.print();
    s4.print();
    s5.print();
    cout<<endl;
    fstream f;
    f.open("abc.txt", ios::out);
    f.write((char*)&s1,sizeof(s1));
     f.write((char*)&s2,sizeof(s2));
      f.write((char*)&s3,sizeof(s3));
       f.write((char*)&s4,sizeof(s4));
        f.write((char*)&s5,sizeof(s5));
    f.close();
    f.open("abc.txt", ios::in);
    while(f){
        Student s ;
        f.read((char*)&s,sizeof(s));
        s.print();
        cout<<"Printed"<<endl<<endl;

    }
    f.close();

      cout<<endl<<endl<<"***************"<<endl<<endl;
        Student s,mystud;
     f.open("abc.txt"); // what is the mode?
     f.seekp(2*sizeof(s),ios::beg);
     Student s_new(69,"Ramesh",69);
     f.write((char*)&s_new,sizeof(s_new));
     f.close();
 cout<<endl<<endl<<"***************"<<endl<<endl;


     f.open("abc.txt", ios::in);
    while(f){
        Student s ;
        f.read((char*)&s,sizeof(s));
        s.print();
        cout<<"Printed"<<endl<<endl;

    }
    f.close();
     mystud.print();

}

ВЫХОД:


Student Name : D Dhar
Student Roll No : 25
Student's Score : 85
Student Name : A Sinha 
Student Roll No : 28
Student's Score : 45
Student Name : B Sinha 
Student Roll No : 29
Student's Score : 49
Student Name : C Sinha 
Student Roll No : 45
Student's Score : 96
Student Name : D Sinha 
Student Roll No : 47
Student's Score : 23

Student Name : D Dhar
Student Roll No : 25
Student's Score : 85
Printed

Student Name : A Sinha 
Student Roll No : 28
Student's Score : 45
Printed

Student Name : B Sinha 
Student Roll No : 29
Student's Score : 49
Printed

Student Name : C Sinha 
Student Roll No : 45
Student's Score : 96
Printed

Student Name : D Sinha 
Student Roll No : 47
Student's Score : 23
Printed

Student Name : 
Student Roll No : 0
Student's Score : 0
Printed



***************



***************

Student Name : D Dhar
Student Roll No : 25
Student's Score : 85
Printed

Student Name : A Sinha 
Student Roll No : 28
Student's Score : 45
Printed

Student Name : Ramesh
Student Roll No : 69
Student's Score : 69
Printed

Student Name : C Sinha 
Student Roll No : 45
Student's Score : 96
Printed

Student Name : D Sinha 
Student Roll No : 47
Student's Score : 23
Printed

Student Name : 
Student Roll No : 0
Student's Score : 0
Printed

Student Name : 
Student Roll No : 0
Student's Score : 0

1 Ответ

1 голос
/ 27 апреля 2019

seekp ()

Устанавливает индикатор положения выхода текущего связанного объекта streambuf. * ​​1004 *

seekg ()

Устанавливает индикатор положения входа текущего связанногоОбъект streambuf. * ​​1008 *

Чтобы иметь возможность обновлять существующие записи, просто откройте файл для чтения и записи.Вы также можете рассмотреть возможность добавления обычных операторов потоковой передачи вместо метода print и т. Д., Чтобы всем было проще его использовать.Кроме того, если в этом

while(f) {
    Student s;
    f.read((char*)&s,sizeof(s));
    s.print();
}

произойдет сбой вашей операции read, вы все равно напечатаете Student, что может привести к проблемам.Лучше проверить статус после прочтения, прежде чем использовать Student.С добавленными потоковыми операторами это становится легко.Пример:

#include <iostream>
#include <fstream>
#include <cstring>

// using namespace std; // don't do that because:
// /1311976/pochemu-ispolzovanie-prostranstva-imen-std-schitaetsya-plohoi-praktikoi

class Student {
private:
    int roll;
    int marks;
    char name[32]; // added 2 chars since padding probably will anyway

public:
    Student(int Roll = 0, char const Name[] = "", int Marks = 0) :
        roll(Roll), marks(Marks), name{}
    {
        // make sure you dont copy more than you've got space for
        // and make sure there's a null terminator at the end.
        std::strncpy(name, Name, sizeof(name) - 1);
        name[sizeof(name) - 1] = '\0';
    }

    // I/O functions
    friend std::ostream& operator<<(std::ostream&, const Student&);
    friend std::ofstream& operator<<(std::ofstream&, const Student&);
    friend std::ifstream& operator>>(std::ifstream&, Student&);
    friend std::fstream& operator<<(std::fstream&, const Student&);
    friend std::fstream& operator>>(std::fstream&, Student&);
};

std::ostream& operator<<(std::ostream& os, const Student& s) {
    os << "Student Name    : " << s.name << "\n";
    os << "Student Roll No : " << s.roll << "\n";
    os << "Student's Score : " << s.marks << "\n";
    return os;
}

std::ofstream& operator<<(std::ofstream& os, const Student& s) {
    os.write(reinterpret_cast<const char*>(&s), sizeof(s));
    return os;
}

std::ifstream& operator>>(std::ifstream& is, Student& s) {
    is.read(reinterpret_cast<char*>(&s), sizeof(s));
    return is;
}

std::fstream& operator<<(std::fstream& os, const Student& s) {
    os.write(reinterpret_cast<const char*>(&s), sizeof(s));
    return os;
}

std::fstream& operator>>(std::fstream& is, Student& s) {
    is.read(reinterpret_cast<char*>(&s), sizeof(s));
    return is;
}

int main() {
    Student s1(25, "D Dhar", 85);
    Student s2(28, "A Sinha ", 45);
    Student s3(29, "B Sinha ", 49);
    Student s4(45, "C Sinha ", 96);
    Student s5(47, "D Sinha ", 23);
    std::cout << s1 << s2 << s3 << s4 << s5 << "\n";

    {
        std::cout << "*** saving students\n";
        std::ofstream ofs("abc.txt");
        ofs << s1 << s2 << s3 << s4 << s5;
        std::cout << "--\n";
    }

    {
        std::cout << "*** reading students\n";
        std::ifstream ifs("abc.txt");
        Student s;
        while(ifs >> s) std::cout << s;
        std::cout << "--\n";
    }

    {
        std::cout << "*** overwriting third student\n";
        Student s_new(69, "Ramesh", 69);
        std::cout << s_new;
        std::fstream fs("abc.txt"); // open for read and write to not truncate it
        fs.seekp(2 * sizeof(Student));
        fs << s_new;
        std::cout << "--\n";
    }

    {
        std::cout << "*** reading students\n";
        std::ifstream ifs("abc.txt");
        Student s;
        while(ifs >> s) std::cout << s;
        std::cout << "--\n";
    }
}
...