Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблемы при работе с бинарным файлом, В стиле С++ 
V
    Опции темы
Kuvaldis
Дата 29.3.2007, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: 11
Всего: 61



Как-то упустил я в свое время работу с файлами как потоками. Теперь догоняю.
Проблема следующая. Реализую работу по прямому доступу к файлу.  Но в режиме ios::ate в файл:
1.  не дописывается информация, а затирается (2005 студия)
2.  дописывается, но после этого больше ничего нельзя ввести (как будто cin забит, хотя я вроде его сбрасываю) (VC++ 6)
3. записывается задом наперед ( Builder 6). ДЛя восстановления полседовательности:
тискаем "создать файл" - append - вводим 5-ки, потом 3-ки
пишет почему-то 5 - 3, хотя пишу в нужное место (упрорядоченное)

Был бы рад услышать конструктивую критику по поводу данной проблемы.
СУВ, Kuvaldis
Вот код:
Код

//---------------------------------------------------------------------------
                        //   ПРЯМОЙ ДОСТУП К ФАЙЛУ //
//---------------------------------------------------------------------------
#include <iostream>
#include <iomanip>
#include <fstream>
#include <stdlib.h>
#include <conio.h>
//---------------------------------------------------------------------------
using namespace std;
//---------------------------------------------------------------------------
const char FILENAME[] = "clients.dat";
const int  LASTLEN  = 15;
const int  FIRSTLEN = 10;
const int  SIZE = 100;
const int  SHARP = 2;
//---------------------------------------------------------------------------
struct  clientData
{
    int     AcctNum;
    char    lastName[LASTLEN];
    char    firstName[FIRSTLEN];
    float   balance;
};
//---------------------------------------------------------------------------
char ViewMenu();

void CreateNewFile();

void AppendFile();

void ViewFile();

void OutputRecord(const clientData & client);
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
    char  choice;

    while (1)
    {
        choice = ViewMenu();
        switch (choice)
        {
            case '1':  CreateNewFile();
                       break;

            case '2':  AppendFile();
                       break;

            case '3':  ViewFile();
                       break;
                       
           case 0x1B:  return 0;
        }
     }   
}
//---------------------------------------------------------------------------
char ViewMenu()
{
    system("cls");
    cout << "1.   Create blank file" << endl;
    cout << "2.   Append data to file" << endl;
    cout << "3.   View file" << endl;
    cout << "ESC. Quit" << endl;

    char sym = _getch ();
    
    return sym;
}
//---------------------------------------------------------------------------
void CreateNewFile()
{
    ofstream  ourCredit(FILENAME, ios::out);

    if ( ! ourCredit )
    {
        cerr << "Unable to create file" << endl;
        _getch ();
        exit(1);
    }

    clientData  blankClient = { 0, "", "", 0 };

    // создаем файл на SIZE записей
    for (int i = 0; i < SIZE; i++)
    {
        ourCredit.write( (char*) &blankClient, sizeof(clientData) );
    }

    ourCredit.close();
    cout << "File created successfully" << endl;
    _getch ();
    return;
}
//---------------------------------------------------------------------------
void AppendFile()
{
    ofstream    ourCredit(FILENAME, ios::ate);

    if ( ! ourCredit )
    {
        cerr << "Unable to open file" << endl;
        _getch ();
        exit(1);
    }

    clientData  client;

    cout << "Input account (0 to stop)" << endl << "? ";
    cin.clear();
    cin.sync();
    
    cin >> client.AcctNum;

    while ( (client.AcctNum > 0) &&  (client.AcctNum < SIZE) )
    {
        cout << "Input First name, Last name, balance" << endl;
        cin >> client.firstName >> client.lastName >> client.balance;

        // позиционирование файлового указателя
        ourCredit.seekp( (client.AcctNum - 1) * sizeof(clientData), ios::beg);
        ourCredit.write( (char*) &client, sizeof(clientData) );
        cout << "Input account" << endl << "? ";
        cin >> client.AcctNum; 
    }

 //   ourCredit.seekp( 0, ios::end );   
    ourCredit.close();
    cout << "File updated successfully" << endl;
    _getch ();
    return;
}
//---------------------------------------------------------------------------
void OutputRecord(const clientData & client)
{
    cout.setf(ios::fixed);
    cout.precision(SHARP);

    cout << setw(11) << client.AcctNum <<
            setw(LASTLEN + 5) <<  client.lastName <<
            setw(FIRSTLEN + 5) <<  client.firstName  <<   
            setw(10) << client.balance << endl;
            
    return;        
}
//---------------------------------------------------------------------------
void ViewFile()
{
    ifstream    ourCredit(FILENAME, ios::in);

    system("cls");
    
    if ( ! ourCredit )
    {
        cerr << "Unable to open file" << endl;
        _getch ();
        exit(1);
    } 
     ourCredit.seekg(0, ios::beg);
     
     cout << "---------------------------------------------------------" << endl;
     cout << setw(11) << "AcctNum" <<
            setw(LASTLEN + 5) <<  "lastName" <<
            setw(FIRSTLEN + 5) <<  "firstName"  <<
            setw(10) << "balance" << endl;

     cout << "---------------------------------------------------------" << endl;

    clientData  client;

    ourCredit.read( (char*) &client, sizeof(clientData) );

    while ( ! ourCredit.eof() )
    {
        if ( client.AcctNum != 0 )
        {
           OutputRecord(client);
        }
        ourCredit.read( (char*) &client, sizeof(clientData) );
    }

    ourCredit.close();
    _getch ();
    return;
}
//---------------------------------------------------------------------------




Эх, не знал, что у меня 800-ое сообщение будет таким грустным :(


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
vinter
Дата 29.3.2007, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Код

 ofstream    ourCredit(FILENAME, ios::out | ios::ate);

вот тут не совсем понятно, ты тут со смещением ниче не напутал?
Код

 ourCredit.seekp( (client.AcctNum - 1) * sizeof(clientData), ios::beg);
        ourCredit.write( (char*) &client, sizeof(clientData) );

а вообще про блемы только в 
Цитата
void AppendFile()


или нет?


--------------------
Мой блог
PM MAIL WWW   Вверх
Kuvaldis
Дата 29.3.2007, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: 11
Всего: 61



vinter, 
Цитата

вот тут не совсем понятно, ты тут со смещением ниче не напутал?

Неа, тут все правильно. Потому что студия 2005 и вижуал 6 пишут правильно
Но даже с 
Код

ofstream    ourCredit(FILENAME, ios::out | ios::ate);

повторный вызов void AppendFile() не делает того, что нужно :(


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
JackYF
Дата 29.3.2007, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Kuvaldis @  29.3.2007,  18:31 Найти цитируемый пост)
еа, тут все правильно. Потому что студия 2005 и вижуал 6 пишут правильно
Но даже с 
Выделить всёкод C++
1:
    
ofstream    ourCredit(FILENAME, ios::out | ios::ate);

повторный вызов void AppendFile() не делает того, что нужно :( 


Если тебе надо Append, может надо ios::app?



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Partizan
Дата 29.3.2007, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 4
Всего: 67



гмм...странно...файл затирается прямо при открытии...
при ios::app не затирается, но и позиция в файле почему то на нужную не изменяется...


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Kuvaldis
Дата 29.3.2007, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: 11
Всего: 61



JackYF, 
Цитата

Если тебе надо Append, может надо ios::app?

ios::app пишет только в конец файла
Мне же надо открыть файл для записи, но его не урезать и с возможностью писать в любое место. Поэтому и использую ios::ate

Это сообщение отредактировал(а) Kuvaldis - 29.3.2007, 18:49


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
vinter
Дата 29.3.2007, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Код

ofstream    ourCredit(FILENAME, ios::out | ios::app | ios::binary);

    if ( ! ourCredit )
    {
        cerr << "Unable to open file" << endl;
        _getch ();
        exit(1);
    }

    clientData  client;

    cout << "Input account (0 to stop)" << endl << "? ";
    
    cin >> client.AcctNum;

    while ( (client.AcctNum > 0) &&  (client.AcctNum < SIZE) )
    {
        cout << "Input First name, Last name, balance" << endl;
        cin >> client.firstName >> client.lastName >> client.balance;

        // позиционирование файлового указателя
        ourCredit.seekp( (client.AcctNum - 1) * sizeof(clientData), ios::beg);
        ourCredit.write( (char*) &client, sizeof(clientData) );
        cout << "Input account" << endl << "? ";
        cin.sync();
        cin.clear();
        cin >> client.AcctNum; 
    }

не знаю че у вас там с позицией, а я последовательно три записи сделал и все ОК smile 


--------------------
Мой блог
PM MAIL WWW   Вверх
Partizan
Дата 29.3.2007, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 4
Всего: 67



=) vinter, что...и даже файл при открытии не затирается? )


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
vinter
Дата 29.3.2007, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(Partizan @  29.3.2007,  18:53 Найти цитируемый пост)
=) vinter, что...и даже файл при открытии не затирается? )

не затирается


--------------------
Мой блог
PM MAIL WWW   Вверх
Partizan
Дата 29.3.2007, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 4
Всего: 67



гммм...странно...у меня такой же код при первом вызове AppendFile его затирает...


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Kuvaldis
Дата 29.3.2007, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: 11
Всего: 61



vinter, 
Твой вариант стал работать в Visual 6. Если бы больше не работал в Bulder, списал бы все на время НО... не работает в 2005 студии
Т.е. все пишется, но почему-то в конец файла, а должно в нужное место :(

Это сообщение отредактировал(а) Kuvaldis - 29.3.2007, 19:04


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
vinter
Дата 29.3.2007, 19:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



нет у меня все нормально(2003),даже несколько раз программу запускал, добавлял выходил, потом смотрел, короче все нормальноsmile


--------------------
Мой блог
PM MAIL WWW   Вверх
Kuvaldis
Дата 29.3.2007, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: 11
Всего: 61



Записи должы выводиться отсортированными по AcctNum 

Это сообщение отредактировал(а) Kuvaldis - 29.3.2007, 19:09


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
vinter
Дата 29.3.2007, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



вкурил походу про позицию, это если вводишь 2, то она должна вторую строку затереть?? если да то у меня тоже с позицией не работает, и не будет это работать надо файл перезаписывать снова, а в этом файле менять нельзя!


--------------------
Мой блог
PM MAIL WWW   Вверх
Kuvaldis
Дата 29.3.2007, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


механик-вредитель
***


Профиль
Группа: Участник Клуба
Сообщений: 1189
Регистрация: 16.6.2006
Где: Минск

Репутация: 11
Всего: 61



Идея такова:
 есть файл с пустыми записями (на 100 эл-тов)
ПО вводимому account я записываю в файл на позицию account новую запись. Поэтому при выводе файла все записи будут или заняты, или свободны. При последовательном (!) чтении файла и выводе его содержимого эл-ты должны (?) выводиться по возрастанию account (они так записывались, вставкой в нужное место)

Это сообщение отредактировал(а) Kuvaldis - 29.3.2007, 19:15


--------------------
Помни - когда ты спишь, враг не дремлет
Спи чаще и дольше, изматывай врага бессоницей
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0594 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.