Переменные захлебываются (C++)

293
03 января 2018, 19:38

Не могу понять почему переменные "захлебываются" после введения второй и тд. записи... Не знаю как это исправить(

Код:

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <cstring>
#include<clocale>
using namespace std;
typedef unsigned int vdt; // изменяемый тип данных (vdt)
struct fileDB {
    char nameF[20] = "\0";         // название файла (nameF, c)
    char typeF[20] = "\0";         // тип файла (typeF, c)
    char locationF[20] = "\0";     // расположение файла (locationF, c)
    char attributeF[20] = "\0";    // атрибут (attributeF, c)
    char dateF[20] = "\0";         // дата создания (dateF, c)
    vdt sizeF = 0;            // размер файла (sizeF, vdt)
};
int main() {
    setlocale(LC_CTYPE, "");
    fileDB *files;
    files = new fileDB;
    fstream *fileDB;
    fileDB = new fstream();
    int menu_flag = -1, case3_flag;
    char nameFS[20] = "\0", typeFS[20] = "\0", dateFS[20] = "\0", attributeFS[20] = "\0", locationFS[20] = "\0"; // перменные символьного типа для сравнения со структурой
    int  sizeFS = 0; // переменные целочисленного типа для сравнения со структурой
    bool have; // если отстуствует искомый процессор, то флаг становится false и выводится: "Совпадений нет."
    while (menu_flag) {
        cout << "1 - Создать новый файл\n";
        cout << "2 - Прочитать файл\n";
        cout << "3 - Поиск\n";
        cout << "0 - Выход\n";
        cout << "Ваш ввод: ";
        cin >> menu_flag;
        switch (menu_flag) {
        case 1: { //создание файла
            fileDB->open("file.db", ios::binary | ios::app);
            char case1_flag[4] = "yes"; // перменная для запроса повторного ввода записи
            while (strcmp(case1_flag, "no") != 0) // цикл для заполнения структуры в файл
            {
                cout << "Введите название файла: ";
                cin >> files->nameF;
                cout << "Введите тип файла: ";
                cin >> files->typeF;
                cout << "Введите расположение файла: ";
                cin >> files->locationF;
                cout << "Введите атрибут файла(A, B, C,...): ";
                cin >> files->attributeF;
                cout << "Введите дата создания файла: ";
                cin >> files->dateF;
                cout << "Введите размер файла в МБ: ";
                cin >> files->sizeF;
                fileDB->write((char*)files, sizeof(fileDB));
                cout << "Добавить еще запись в файл yes/no?: "; //запрос повтороного ввода записи в файл
                fflush(stdin);
                cin >> case1_flag;
            }
        }
                fileDB->close();
                break;
        case 2: {
            fileDB->open("file.db", ios::binary | ios::in);
            if (!fileDB->is_open())
            {
                cout << "\nФайл не найден\n\n";
                break;
            }
            fileDB->close();
            fileDB->open("file.db", ios::binary | ios::in);
            while (fileDB->read((char*)files, sizeof(fileDB))) {
                cout << "\n|================================|\n";
                cout << "Название файла: " << files->nameF << endl;
                cout << "Тип файла: " << files->typeF << endl;
                cout << "Расположение файла: " << files->locationF << endl;
                cout << "Атрибут файла: " << files->attributeF << endl;
                cout << "Дата создания файла: " << files->dateF << endl;
                cout << "Размер файла: " << files->sizeF << endl;
                cout << "|================================|\n\n";
            }
        }
                fileDB->close();
                break;
        case 3: {
            fileDB->open("file.db", ios::binary | ios::in);
            if (!fileDB->is_open())
            {
                cout << "\nФайл не найден\n\n";
                break;
            }
            fileDB->close();
            case3_flag = -1;
            while (case3_flag) {
                cout << "\n1 - Поиск по названию файла\n";
                cout << "2 - Поиск по типу файла\n";
                cout << "3 - Поиск по расположению файла\n";
                cout << "4 - Поиск по атрибуту файла\n";
                cout << "5 - Поиск по дате создания файла\n";
                cout << "6 - Поиск по размеру файла\n";
                cout << "0 - Назад\n";
                cout << "Ваш ввод: ";
                cin >> case3_flag;
                switch (case3_flag) {
                case 1: {
                    fileDB->open("file.db", ios::binary | ios::in);
                    have = false;
                    cout << "Введите название файла: ";
                    cin >> nameFS;
                    while (fileDB->read((char*)files, sizeof(fileDB))) {
                        if (strcmp(nameFS, files->nameF) == 0) {
                            cout << "\n|================================|\n";
                            cout << "Название файла: " << files->nameF << endl;
                            cout << "Тип файла: " << files->typeF << endl;
                            cout << "Расположение файла: " << files->locationF << endl;
                            cout << "Атрибут файла: " << files->attributeF << endl;
                            cout << "Дата создания файла: " << files->dateF << endl;
                            cout << "Размер файла: " << files->sizeF << endl;
                            cout << "|================================|\n\n";
                            have = true;
                        }
                    }
                    if (!have)
                        cout << "\nСовпадений нет\n";
                    fileDB->close();
                }
                        break;
                case 2: {
                    fileDB->open("file.db", ios::binary | ios::in);
                    have = false;
                    cout << "Введите тип файла: ";
                    cin >> typeFS;
                    while (fileDB->read((char*)files, sizeof(fileDB))) {
                        if (strcmp(typeFS, files->typeF) == 0) {
                            cout << "\n|================================|\n";
                            cout << "Название файла: " << files->nameF << endl;
                            cout << "Тип файла: " << files->typeF << endl;
                            cout << "Расположение файла: " << files->locationF << endl;
                            cout << "Атрибут файла: " << files->attributeF << endl;
                            cout << "Дата создания файла: " << files->dateF << endl;
                            cout << "Размер файла: " << files->sizeF << endl;
                            cout << "|================================|\n\n";
                            have = true;
                        }
                    }
                    if (!have)
                        cout << "\nСовпадений нет\n";
                    fileDB->close();
                }
                        break;
                case 3: {
                    fileDB->open("file.db", ios::binary | ios::in);
                    have = false;
                    cout << "Введите расположение файла:";
                    cin >> locationFS;
                    while (fileDB->read((char*)files, sizeof(fileDB))) {
                        if (strcmp(locationFS, files->locationF) == 0) {
                            cout << "\n|================================|\n";
                            cout << "Название файла: " << files->nameF << endl;
                            cout << "Тип файла: " << files->typeF << endl;
                            cout << "Расположение файла: " << files->locationF << endl;
                            cout << "Атрибут файла: " << files->attributeF << endl;
                            cout << "Дата создания файла: " << files->dateF << endl;
                            cout << "Размер файла: " << files->sizeF << endl;
                            cout << "|================================|\n\n";
                            have = true;
                        }
                    }
                    if (!have)
                        cout << "\nСовпадений нет\n";
                    fileDB->close();
                }
                        break;
                case 4: {
                    fileDB->open("file.db", ios::binary | ios::in);
                    have = false;
                    cout << "Введите атрибут файла: ";
                    cin >> attributeFS;
                    while (fileDB->read((char*)files, sizeof(fileDB))) {
                        if (strcmp(attributeFS, files->attributeF) == 0) {
                            cout << "\n|================================|\n";
                            cout << "Название файла: " << files->nameF << endl;
                            cout << "Тип файла: " << files->typeF << endl;
                            cout << "Расположение файла: " << files->locationF << endl;
                            cout << "Атрибут файла: " << files->attributeF << endl;
                            cout << "Дата создания файла: " << files->dateF << endl;
                            cout << "Размер файла: " << files->sizeF << endl;
                            cout << "|================================|\n\n";
                            have = true;
                        }
                    }
                    if (!have)
                        cout << "\nСовпадений нет\n";
                    fileDB->close();
                }
                        break;
                case 5: {
                    fileDB->open("file.db", ios::binary | ios::in);
                    have = false;
                    cout << "Введите дату создания файла: ";
                    cin >> dateFS;
                    while (fileDB->read((char*)files, sizeof(fileDB))) {
                        if (strcmp(dateFS, files->dateF) == 0) {
                            cout << "\n|================================|\n";
                            cout << "Название файла: " << files->nameF << endl;
                            cout << "Тип файла: " << files->typeF << endl;
                            cout << "Расположение файла: " << files->locationF << endl;
                            cout << "Атрибут файла: " << files->attributeF << endl;
                            cout << "Дата создания файла: " << files->dateF << endl;
                            cout << "Размер файла: " << files->sizeF << endl;
                            cout << "|================================|\n\n";
                            have = true;
                        }
                    }
                    if (!have)
                        cout << "\nСовпадений нет\n";
                    fileDB->close();
                }
                        break;
                case 6: {
                    fileDB->open("file.db", ios::binary | ios::in);
                    have = false;
                    cout << "Введите размер файла: ";
                    cin >> sizeFS;
                    while (fileDB->read((char*)files, sizeof(fileDB))) {
                        if (sizeFS >= files->sizeF) {
                            cout << "\n|================================|\n";
                            cout << "Название файла: " << files->nameF << endl;
                            cout << "Тип файла: " << files->typeF << endl;
                            cout << "Расположение файла: " << files->locationF << endl;
                            cout << "Атрибут файла: " << files->attributeF << endl;
                            cout << "Дата создания файла: " << files->dateF << endl;
                            cout << "Размер файла: " << files->sizeF << endl;
                            cout << "|================================|\n\n";
                            have = true;
                        }
                    }
                    if (!have)
                        cout << "\nСовпадений нет\n";
                    fileDB->close();
                }
                        break;
                default:break;
                }//end of switch
            }
            fileDB->close();
        }
                break;
        case 0:
            return 0; // выход из программы
        default:break;
        }
    }
    return 0;
}

Вывод:

1 - Создать новый файл
2 - Прочитать файл
3 - Поиск
0 - Выход
Ваш ввод: 1
Введите название файла: test
Введите тип файла: txt
Введите расположение файла: c:\
Введите атрибут файла(A, B, C,...): b
Введите дата создания файла: 12.12.12
Введите размер файла в МБ: 12
Добавить еще запись в файл yes/no?: y
Введите название файла: qwe
Введите тип файла: asd
Введите расположение файла: c:\
Введите атрибут файла(A, B, C,...): a
Введите дата создания файла: 13.13.12
Введите размер файла в МБ: 14
Добавить еще запись в файл yes/no?: no
1 - Создать новый файл
2 - Прочитать файл
3 - Поиск
0 - Выход
Ваш ввод: 2
|================================|
Название файла: test
Тип файла: asd
Расположение файла: c:\
Атрибут файла: a
Дата создания файла: 13.13.12
Размер файла: 14
|================================|

|================================|
Название файла: qwe
Тип файла: asd
Расположение файла: c:\
Атрибут файла: a
Дата создания файла: 13.13.12
Размер файла: 14
|================================|
1 - Создать новый файл
2 - Прочитать файл
3 - Поиск
0 - Выход
Ваш ввод:...

И так, что происходит когда я создаю новый файл: я заполняю все параметры, после хочу удивить результат, но вижу что прежние записи были переписаны на новую и при этом "название" не меняется. А как должно быть: при добавлении новой записи, запись должна добавиться, а старые не должны изменяться.

Answer 1

У вас есть тип struct fileDB и локальная переменная fstream *fileDB; с тем же именем. Соответственно когда вы пишите fileDB->write((char*)files, sizeof(fileDB)); или читаете fileDB->read((char*)files, sizeof(fileDB) будет записано количество байт, соответствующее размеру локальной переменной, то бишь всего 4 или 8 байт. Чтобы избегать таких проблем следует: во-первых давать имена с таким расчетом, чтобы идентификаторы для типов и переменных никогда не пересекались (например разный регистр и / или префикс СfileDB - тип и file_db - переменная), во-вторых по возможности применять sizeof непосредственно к переменной (sizeof(*files) - размер структуры, на которую указывает files), в-третьих проверять количество реально записанных / прочитанных байт.

Помимо этого, старайтесь избегать копипасты, а то ваш код неимоверно раздут. Например с ходу можно вынести в отдельный метод код печати содержимого записи, а то сейчас он продублирован 7 раз.

Инициализацию структуры можно тоже упростить, "\0" не нужны:

struct fileDB {
    char nameF[20]{};      // название файла (nameF, c)
    char typeF[20]{};      // тип файла (typeF, c)
    char locationF[20]{};  // расположение файла (locationF, c)
    char attributeF[20]{}; // атрибут (attributeF, c)
    char dateF[20]{};      // дата создания (dateF, c)
    vdt sizeF{};           // размер файла (sizeF, vdt)
};

или вообще убрать инициализацию отдельных полей и производить инициализацию нулями при создании объекта files = new fileDB{};

READ ALSO
Где указатель хранит значение

Где указатель хранит значение

Если указатель хранит адресс ячейки, то где хранится само значение?? например где хранится число 5?

241
Что означают данные строки в коде?

Что означают данные строки в коде?

Что ознают данные строки в коде ?

270
Ошибка в отображении формата данных SimpleDateFormat Java

Ошибка в отображении формата данных SimpleDateFormat Java

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

325