Не могу понять почему переменные "захлебываются" после введения второй и тд. записи... Не знаю как это исправить(
Код:
#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 - Выход
Ваш ввод:...
И так, что происходит когда я создаю новый файл: я заполняю все параметры, после хочу удивить результат, но вижу что прежние записи были переписаны на новую и при этом "название" не меняется. А как должно быть: при добавлении новой записи, запись должна добавиться, а старые не должны изменяться.
У вас есть тип 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{};
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Если указатель хранит адресс ячейки, то где хранится само значение?? например где хранится число 5?
добрый день помогите разобраться пожалуйста