Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 23, средняя оценка - 4.61
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
#1

Файл произвольного доступа - C++

03.07.2011, 14:36. Просмотров 3179. Ответов 34
Метки нет (Все метки)

Очень прошу помощи так как не могу с ними разобраться который день, видать делаю одну и ту же ошибку но не нахожу. Создаю свой класс и потом когда пытаюсь его записать и считать возникают ошибки.
Ну да наверное проще начать обо всём по порядку чтобы не запутывать.

Проблема первая: файл каждый раз после записи 10 объектов моего класса в бинарном режиме при открытии текстовым редактором выглядит по разному, хотя размер его одинаковый, это меня настораживает.

Пример: запускаю скомпилированное приложение чтобы оно записало 10 объектов моего класса ClientData созданных конструктором по умолчанию и открываю через текстовый редактор и вижу символы :u.ы-I, закрываю и открываю опять своё приложение и вижу уже символы :ucИќ, за третим разом :uО(фҐ , тоесть первые 2 символа всегда те же, а остальные меняются, так ведь быть не должно? Значит ошибка у меня в классе? Тогда просьба подсказать где именно вроде строки уже не использую и все типы данных не должны меняться ...

Сам класс ClientData мой представляет собой класс с 3мя данными (номер, имя, баланс) и set и get методами для них (проверок кое-где нету, но не в них суть).


ClientData.h (Заголовочный файл к классу)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef CLIENTDATA_H
#define CLIENTDATA_H
 
#include <string>
using std::string;
 
 
class ClientData
{
public:
    //конструктор по умолчанию который устанавливает
    //номер =0, имя = пустой строке и баланс =0
    ClientData(int=0,string="",double=0.0);
 
    void setID(int);
    int getID() const;
 
    void setName(string);
    string getName() const;
 
    void setBalance(double);
    double getBalance() const;
 
 
private:
    int ID; //номер
    char name[15]; //имя
    double balance; // баланс
};
 
#endif
ClientData.cpp (реализация самого класса)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <string>
using std::string;
 
#include <cstring>
#include "ClientData.h"
 
ClientData::ClientData(int i, string n, double b)
{
    setID(i);
    setName(n);
    setBalance(b);
}
 
void ClientData:: setID(int i)
{
    ID=i;
}
 
int ClientData:: getID() const
{
    return ID;
}
 
void ClientData:: setName(string n)
{
    strncpy(name,n.data(),14);
}
 
string ClientData:: getName() const
{
    return name;
}
 
void ClientData:: setBalance(double b)
{
    balance=b;
}
 
double ClientData:: getBalance() const
{
    return balance;
}
main(совершаю только запись в файл 10 объектов типа ClientData
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <iomanip>
#include <fstream>
#include "ClientData.h"
using namespace std;
 
void newRecord(fstream&);
int menu();
void print(fstream&);
void print2(fstream&);
 
int main()
{
    //создаю объект типа ClientData
    ClientData client; 
    
    //открываю файл для чтения и записи в бинарном режиме
    fstream file("trans.dat",ios::binary|ios::in|ios::out);
    if (!file)
     cerr<<"Error";
 
    //записываю 10 моих объектов в файл
    for (int i=0;i<10;i++)
     file.write(reinterpret_cast<const char*>(&client),sizeof(ClientData));
}
Очень прошу помочь разобраться.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.07.2011, 14:36
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Файл произвольного доступа (C++):

Файл произвольного доступа - C++
Читаю Дейтелов, про файлы произвольного доступа. Написал вроде как по примеру, но что-то идет не так. Идея такая - создается файл, в нем...

Файл произвольного доступа - C++
Здравствуйте, снова к файлам, такая задача. Допустим, у меня есть текстовый файл с данными - код, название, количество, и со значениями...

Не могу прочитать файл произвольного доступа с конца - C++
Странное происходит в функции read_file, а именно не работает seekg. Почему-то читается всё время последнее значение. Почему так и что с...

Обработка файлов произвольного доступа - C++
Создать файл, содержащий массив указателей на упорядоченные в алфавитном порядке строки, представленные записями переменной длины....

Детектировать итератор произвольного доступа - C++
здравствуйте, нужно детектировать итератор произвольного доступа... это не работает: template&lt; typename... &gt; using void_t = void; ...

Создание файла произвольного доступа. - C++
#include &lt;iostream.h&gt; #include &lt;fstream.h&gt; #include &lt;stdlib.h&gt; #define number 100 struct clientData { int acctNum; ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Bers
Заблокирован
03.07.2011, 21:31 #16
Вы сохраняете объект с мусором. Избавьтесь от мусора в массиве чаров, и будит вам щастье. В чом проблема то?
ForEveR
В астрале
Эксперт С++
7971 / 4733 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
03.07.2011, 21:57 #17
Gepar, boost::serialization

Не по теме:

А вообще это круто - искать инфу про boost на cplusplus.com.
А в прошлой теме дан вариант записи/считывания через serialization... Посмотри - почитай. Сто процентов получится лучше, чем самому писать в бинарники.

grizlik78
Эксперт С++
1908 / 1440 / 111
Регистрация: 29.05.2011
Сообщений: 2,996
03.07.2011, 23:00 #18
Сообщение было отмечено автором темы, экспертом или модератором как ответ
В функции newRecord:
C++
1
2
        file.write(reinterpret_cast<const char*>(&account),sizeof(ClientData));
        file.read(reinterpret_cast<char*>(&account),sizeof(ClientData));
Какой-такой account? Чего вы нам голову морочите? account это int, а не ClientData!
Bers
Заблокирован
03.07.2011, 23:57 #19
кстати, да. 50 и 46 строчка.
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
04.07.2011, 14:25  [ТС] #20
Тьфу-ты ну ты, вот где собака была зарыта Теперь поправил и оно и сохранило и считало нормально данные (мусор отбрасывается при выводе так как о уже после '\0'). Ну что же, теперь осталось дописать остальные функции по работе с файлом.

Кстати ещё такой вопрос относительно этого класса: как переименовывать созданный файл? Ну был 1.dat, а я после того как скопировал с него данные хочу чтобы он стал 123.dat например. Есть ли в с++ для этого функции какие или надо использовать возможности виндовс через system("") ?

Добавлено через 1 минуту
ForEveR, ну я хочу разобраться с этим методом записи до конца, а потом уже с другими потому и не воспользовался им.

Bers, так а где мусор то, а если без мусора то тогда как по вашему должна выглядеть функция по записи имени в символьный массив (это чтобы ещё и при открытии текстовым редактором файла он выглядел всегда одинаково, хотя это уже и не столь важно).
Bers
Заблокирован
04.07.2011, 14:38 #21
Чорт попозже буду
easybudda
Модератор
Эксперт CЭксперт С++
9530 / 5523 / 932
Регистрация: 25.07.2009
Сообщений: 10,608
04.07.2011, 18:56 #22
Цитата Сообщение от Gepar Посмотреть сообщение
Есть ли в с++ для этого функции
rename
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
08.07.2011, 01:25  [ТС] #23
easybudda, годиться, а теперь бы ещё чего подобного на удаление файла (задача обновить старый файл новым, то есть удалить старый и переименовать новый чтобы он назывался так же как и старый).
easybudda
Модератор
Эксперт CЭксперт С++
9530 / 5523 / 932
Регистрация: 25.07.2009
Сообщений: 10,608
08.07.2011, 01:28 #24
Цитата Сообщение от Gepar Посмотреть сообщение
а теперь бы ещё чего подобного на удаление файла
remove
пример
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
08.07.2011, 12:22  [ТС] #25
Годиться, сейчас попробую применить.
Ну и ещё один вопрос что возник при чтении книги: а как-то можно указать постоянные пути к файлу? Пробовал писать что-то вроде open("c:\1.txt",ios::int) но оно хоть и компилируется, но файл не видит тогда ни в корне диска с, ни в папке с программой, подозреваю что оно начинает искать в папке с программой файл с именем "c:\1.txt" и не находит его.
asics
Freelance
Эксперт С++
2846 / 1783 / 144
Регистрация: 09.09.2010
Сообщений: 3,841
08.07.2011, 12:25 #26
Gepar, Поставь двойной бэкслеш: c:\\1.txt
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
08.07.2011, 16:00  [ТС] #27
А вот ещё пока класс пишу возник вопрос: как почистить файл от данных (файл последовательного доступа, просто символьные данные в нём). Можно бы закрыть файл и открыть файл снова например (ios::out) и тогда всё содержимое должно убраться, но так как планируется это делать из функции то тогда вопрос связанный с этим: как узнать в функции какой же файл ей передан ?Есть функция например
void del(fstream& file), как же узнать что этот file является моим 1.txt например? Тогда бы я смог его закрыть и открыть в функции снова например чтобы почистить, хотя может есть и просто функция чтобы файл очистить то?

Добавлено через 4 минуты
asics, так работает, странно что я сам с двумя слешами не додумался попробовать файл открывать.
easybudda
Модератор
Эксперт CЭксперт С++
9530 / 5523 / 932
Регистрация: 25.07.2009
Сообщений: 10,608
08.07.2011, 16:04 #28
Цитата Сообщение от Gepar Посмотреть сообщение
может есть и просто функция чтобы файл очистить то?
truncate
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
09.07.2011, 19:06  [ТС] #29
А узнать из функции что за файл ей передали всё же можно (получая только файл)? Это так, для общего развития, ну там например чтобы функция print выводила в начале название файла что она печатает, только именно функция, а не в main там перед тем как печатать файл уже. Возможность получить название класса объект которого получен есть ведь, вот думаю и здесь может всё же что-то есть изначально.

Добавлено через 2 минуты
Это заодно и помогло бы с функцией remove, которой название файла же надо получить. Оно то можно сделать символьную строку в main и её и передавать как аргумент сначала при создании файла, а потом и при удалении, но хотелось бы похитрее

Добавлено через 5 часов 25 минут
Что-то не подключается этот truncate с #include <unistd.h>, всё равно пишет что не объявлен никакой truncate.

Добавлено через 51 минуту
И ещё маленький вопрос (надеюсь не задолбал я всех ещё ): есть ли какая функция для работы с файлами чтобы убирала сразу и конец файла и устанавливала курсор в начало файла? Я постоянно то забуду курсор перевести то метку конца файла сбросить и потом сижу ищу где я протупил, было бы хорошо будь одна функция делающая и первое и второе.
asics
Freelance
Эксперт С++
2846 / 1783 / 144
Регистрация: 09.09.2010
Сообщений: 3,841
09.07.2011, 19:11 #30
Цитата Сообщение от Gepar Посмотреть сообщение
есть ли какая функция для работы с файлами чтобы убирала сразу и конец файла и устанавливала курсор в начало файла?
http://www.cplusplus.com/reference/i...istream/seekg/
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.07.2011, 19:11
Привет! Вот еще темы с ответами:

Пишу итератор произвольного доступа - C++
Пишу итератор произвольного доступа. По минимуму он должен поддерживать несколько операций, но меня смутила операция n+it, где n это целое...

Создание файла произвольного доступа - C++
Здравствуйте.Ни как не могу разобраться с файлами произвольного доступа.Но эта тема посвящена именно созданию таких файлов. #include...

В чем ошибка(файлы произвольного доступа) - C++
#include &lt;iostream&gt; #include &lt;fstream&gt; #include &lt;Windows.h&gt; using namespace std; struct PHONE { char Company;//комания ...

Корень произвольного степени из произвольного числа, введенного с клавиатуры - C++
Не применяя встроенных функций, найти корень произвольного степени из произвольного числа, введенного с клавиатуры. Из четырех первых цифр...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
09.07.2011, 19:11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru