Файловая программа не перестанет отображать мусорные значения

#c #file

#c #файл

Вопрос:

Я пытаюсь вставить объект в файл, а затем прочитать объект для отображения данных студента, но когда он переходит к отображению, программа просто переходит в бесконечный цикл и начинает отображать 0, который я инициализировал в конструкторе.Я просто не понимаю, что происходит. Я использую Visual Studio 17 на всякий случай, если кому-то интересно. Я даже пытался создать новый файл с именем Student.txt в том же каталоге, что и программа, но она не будет работать. Может кто-нибудь объяснить мне, что я делаю не так?

 #include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

//class to handle individual record
class Student 
{
public:
    char name[20];
    int year;
    char division;
    char address[50];
    int rollno;
    Student()
    {
        strcpy_s(name," ");
        strcpy_s(address, " ");
        rollno = 0;
        year = 0;
        division = 0;
    }
};
class operations
{

    public:
        void insertdata();
        void printg();
};
void operations::insertdata()
{
    int n;
    cout << "nEnter how many student data you want to insert:";
    cin >> n;
    fstream fin;
    Student obj;
    fin.open("Student.txt", ios::in | ios::out | ios::binary| ios::trunc);
    if (!fin)
    {
        cout<<"nFILE NOT Opened!";
    }
    for (int v = 0; v < n; v  )
    {

        cout << "nEnter Roll no:";
        cin >> obj.rollno;
        cout << "nEnter Name:";
        cin.ignore();
        cin >> obj.name;
        cout << "nEnter year:";
        cin >> obj.year;
        cout << "nEnter division:";
        cin >> obj.division;
        cout << "nEnter Address:";
        cin.ignore();
        cin >> obj.address;
        fin.seekp(0, ios::end);
        fin.write((char*)amp;obj, sizeof(obj));
    }
    fin.close();
}

void operations::printg()
{
    Student obj;
    fstream fin("Student.txt", ios::in | ios::out | ios::binary);
    fin.seekg(0, ios::beg);
    fin.read((char*)amp;obj, sizeof(obj));
    if (!fin)
    {
        cout << "n FIle doenst exist";
    }
    while (!fin.eof())
    {
        cout << "n" << obj.name;
        cout << "n" << obj.year;
        cout << "n" << obj.division;
    }
    fin.close();
}
int  main() {

    operations obj;
    obj.insertdata();
    obj.printg();
    system("pause");
    return 0;
}
  

Комментарии:

1. Вы будете удивлены, узнав, что вашей программе полностью не удается открыть файл, и поскольку она не утруждает себя проверкой успешного открытия файла, конечным результатом является мусор, который вы наблюдали. И причина, по которой ваша программа полностью не может открыть файл, заключается в том, что, C как вы, должно быть, уже знаете, » n» — это символ новой строки, а не строка, состоящая из обратной косой черты, за которой следует буква «n». Теперь посмотрите на имя файла, который вы пытаетесь открыть, и посмотрите, сможете ли вы самостоятельно разобраться в своей ошибке.

2. @SamVarshavchik Не могли бы вы объяснить подробнее, я имею в виду, считается ли » student» как escape-последовательность » n»?

3. Каждая обратная косая черта является escape-последовательностью.

4. @SamVarshavchik Да, спасибо. Чтобы указать путь наоборот «/» , я просто скопировал path из проводника Windows, даже не задумываясь.

Ответ №1:

Несколько неправильных действий:

  • Писать объекты типа fin.write((char*)amp;obj, sizeof(obj)); — плохая идея. Компилятор может в любой момент решить использовать разное заполнение между элементами для ваших Student объектов, поэтому ваш формат файла подобен квантовой частице: вы на самом деле не знаете, как был выложен файл.

  • strcpy_s принимает 3 параметра, а не 2. В любом случае, не используйте их, они на самом деле не переносимы (даже если они соответствуют стандарту C).

  • Ваши пути неверны, поэтому файл не откроется (как объясняет Сэм в комментарии).

  • Даже если вам удалось открыть файл, в operations::printg() вы не читаете файл, поэтому вы не получите никаких данных.

  • Зачем вам operations класс? Я предполагаю, что она предназначена для расширения в будущем, но кажется странной. Если вы не собираетесь указывать состояние, используйте namespace вместо этого.

Комментарии:

1. Я изменил свой код, но теперь он успешно печатает введенные данные, но по-прежнему переходит в бесконечный цикл. Пожалуйста, смотрите.

2. Решил это. Принимаю это как ответ.