std::string и fstream
От: R1K0 Россия  
Дата: 02.09.09 07:18
Оценка: :))
Всем привет. Может я туплю, но почему-то проблема со строками и чтением их из файла.

Вот код записи в файл:

        SetCurrentDirectory(_rootDir.c_str());
    _metaFile.open(_metaFileName.c_str(), ios::binary | ios::app | ios::out);
    _metaFile.write((char *) record_, sizeof(cCachedFile));
    _metaFile.close();


Все данные на момент записи в переменной record_ соответствуют истине. Класс cCachedFile выглядит так (по сути это не более чем структура):

class cCachedFile
{
    public:
        string  url;
        string  fileName;
        string  pathToFile;
        UINT    entryID;
        UINT    sessionID;
        ULONGLONG fileSize;
        BOOL    wasDownloaded;
};


Чтение из файла идет таким образом:

    if (FileExists(_metaFileName.c_str()))
    {
        _metaFile.open(_metaFileName.c_str(), ios::binary | ios::in | ios::app);

        _metaFile.seekg(ios_base::beg);
        while (! _metaFile.eof())
        {
            cCachedFile * fl = new cCachedFile();
            _metaFile.read((char *) fl, sizeof(cCachedFile));
            if (_metaFile.gcount() == 0)
                break;
            else
                _listFiles.push_back(fl);
        }
    }


Скажите, пожалуйста, что тут не так, ибо когда файл считан в vector, то поля url и pathToFile содержат мусор, тогда как все все остальные (включая fileName) содержат именно то, что должны.
Re: std::string и fstream
От: catBasilio  
Дата: 02.09.09 07:32
Оценка:
Здравствуйте, R1K0, Вы писали:

RK>Всем привет. Может я туплю, но почему-то проблема со строками и чтением их из файла.


RK>
RK>class cCachedFile
RK>{
RK>    public:
RK>        string  url;
RK>        string  fileName;
RK>        string  pathToFile;
RK>        UINT    entryID;
RK>        UINT    sessionID;
RK>        ULONGLONG fileSize;
RK>        BOOL    wasDownloaded;
RK>};
RK>


RK>Скажите, пожалуйста, что тут не так, ибо когда файл считан в vector, то поля url и pathToFile содержат мусор, тогда как все все остальные (включая fileName) содержат именно то, что должны.


std::string неслзя тупо взять и записать как структуру, потому-что это полнценный класс, с указателями и т.д.

И вообще нехорошо записывать так как ты делаешь. если уж нужно что-то в поток записать, то переопредели операторы << и >> для работы с твоим классом


ofstream& operator<< (ofstream& ofs, cCachedFile& a)
{
  ofs << a.url;
  ofs << a.fileName; 
  ...

  return ofs;
}

ifstream& operator >> (ifstream& ifs, cCachedFile& a)
{
  ifs >> a.url;
  ifs >> a.fileName; 
  ...

  return ifs;
}



запись:
 metaFile << _record;


чтение:

metaFile >> _record;
UNIX way — это когда тебе вместо туалетной бумаги дают топор, рубанок и карту близлежащего леса
Re[2]: std::string и fstream
От: R1K0 Россия  
Дата: 02.09.09 08:03
Оценка:
Здравствуйте, catBasilio

Большой спос

У меня к тебе еще один вопросик. Вот допустим появилась ситуация, когда мне необходимо изменить одну из записей в файле, или же вообще удалить её. Можно ли сделать это средствами fstream? И, если да, то как?

Может ссылочка какая есть или еще чего?
Re[3]: std::string и fstream
От: abrec Россия  
Дата: 02.09.09 08:27
Оценка:
Здравствуйте, R1K0, Вы писали:

RK>Здравствуйте, catBasilio


RK>Большой спос


RK>У меня к тебе еще один вопросик. Вот допустим появилась ситуация, когда мне необходимо изменить одну из записей в файле, или же вообще удалить её. Можно ли сделать это средствами fstream? И, если да, то как?


RK>Может ссылочка какая есть или еще чего?


Хочется свой лисапед аля новая крутая БД написать? Правильней в файле хранить данные а не обрабатывать.
Re[4]: std::string и fstream
От: R1K0 Россия  
Дата: 02.09.09 08:29
Оценка:
Здравствуйте, abrec, Вы писали:

A>Хочется свой лисапед аля новая крутая БД написать? Правильней в файле хранить данные а не обрабатывать.


Неа. Храниться и будут, а изменятся если и будут, то настолько редко, что БД для этого прикручивать не хочется.
Re[5]: std::string и fstream
От: abrec Россия  
Дата: 02.09.09 08:32
Оценка:
Здравствуйте, R1K0, Вы писали:

RK>Здравствуйте, abrec, Вы писали:


A>>Хочется свой лисапед аля новая крутая БД написать? Правильней в файле хранить данные а не обрабатывать.


RK>Неа. Храниться и будут, а изменятся если и будут, то настолько редко, что БД для этого прикручивать не хочется.


Да я про то, что правка, добавление, удаление прямо в файле — это типа БД. Да и то они так не делают. Тебе это надо?
Что мешает считать файл в типа вектор структур поправить нужную (добавить удалить) и сбросить обратно в файл.
Re[6]: std::string и fstream
От: R1K0 Россия  
Дата: 02.09.09 08:57
Оценка:
Здравствуйте, abrec, Вы писали:

A>Да я про то, что правка, добавление, удаление прямо в файле — это типа БД. Да и то они так не делают. Тебе это надо?

A>Что мешает считать файл в типа вектор структур поправить нужную (добавить удалить) и сбросить обратно в файл.

Ничего не мешает Спос за совет.
Re[6]: std::string и fstream
От: R1K0 Россия  
Дата: 02.09.09 10:10
Оценка:
Здравствуйте, abrec.

Вот пытаюсь делать по совету и столкнулся с такой проблемой:
1. Файл создан успешно;
2. По завершению работы в него сбрасываются все элементы вектора;
3. Перезапуск проги — считываю информацию из файла успешно;
4. Опять дохожу до завершения работы... и вот тут начинается самое интересное:
4.1. Открываю файл с флагами ios::binary | ios::trunc | ios::out;
4.2. Все хорошо — файл обрезается до нулевой отметки;
4.3. Далее я хочу записать в файл информацию из вектора — что и делаю;
4.4. Но по завершении работы проги вижу — что файл так и остался пустым.

Функция записи в файл и в 1й иво 2й запуск одинаковая. Из-за чего это может возникнуть скажите ПЛЗ.
Re[7]: std::string и fstream
От: abrec Россия  
Дата: 02.09.09 10:18
Оценка:
Здравствуйте, R1K0, Вы писали:

RK>Здравствуйте, abrec.


RK>Вот пытаюсь делать по совету и столкнулся с такой проблемой:

RK>1. Файл создан успешно;
RK>2. По завершению работы в него сбрасываются все элементы вектора;
RK>3. Перезапуск проги — считываю информацию из файла успешно;
RK>4. Опять дохожу до завершения работы... и вот тут начинается самое интересное:
RK> 4.1. Открываю файл с флагами ios::binary | ios::trunc | ios::out;
RK> 4.2. Все хорошо — файл обрезается до нулевой отметки;
RK> 4.3. Далее я хочу записать в файл информацию из вектора — что и делаю;
RK> 4.4. Но по завершении работы проги вижу — что файл так и остался пустым.

RK>Функция записи в файл и в 1й иво 2й запуск одинаковая. Из-за чего это может возникнуть скажите ПЛЗ.


ну может надо так
1.open
2.read
3.close

4.open
5.write
6.flush
7.close
Re[8]: std::string и fstream
От: R1K0 Россия  
Дата: 02.09.09 10:27
Оценка:
Здравствуйте, abrec, Вы писали:

A>ну может надо так

A>1.open
A>2.read
A>3.close

A>4.open

A>5.write
A>6.flush
A>7.close

К сожалению не прокатило
Вот на всякий случай код читалки/записи с добавленным методов flush():

void cCacher::DB2Memory()
{
    if (FileExists(_metaFileName.c_str())) // файл есть и его можно посмотреть
    {
        _metaFile.open(_metaFileName.c_str(), ios::binary | ios::in | ios::app);

        _metaFile.seekg(ios_base::beg);
        while (! _metaFile.eof())
        {
            cCachedFile * fl = new cCachedFile();
            _metaFile.read((char *) fl, sizeof(cCachedFile));
            if (_metaFile.gcount() == 0)
            {
                delete fl;
                break;
            }
            else
                _listFiles.push_back(fl);
        }
    }
    else // иначе просто создание файла
        _metaFile.open(_metaFileName.c_str(), ios::binary | ios::trunc | ios::out);

    _metaFile.close();
}

void cCacher::Memory2DB()
{
    SetCurrentDirectory(_rootDir.c_str());
    _metaFile.open(_metaFileName.c_str(), ios::binary | ios::trunc | ios::out);

    for (int i = 0; i < _listFiles.size(); i++)
    {
        cCachedFile * fl = _listFiles.at(i);
        _metaFile.write((char *) fl, sizeof(cCachedFile));
    }

    _metaFile.flush();
    _metaFile.close();
Re[9]: std::string и fstream
От: abrec Россия  
Дата: 02.09.09 10:39
Оценка:
Здравствуйте, R1K0, Вы писали:

RK>
RK>void cCacher::DB2Memory()
RK>{
RK>    if (FileExists(_metaFileName.c_str())) // файл есть и его можно посмотреть
RK>    {
RK>        _metaFile.open(_metaFileName.c_str(), ios::binary | ios::in | ios::app);

зачем ios::app на чтении?

RK>        _metaFile.seekg(ios_base::beg);

и тогда это

RK>        while (! _metaFile.eof())
RK>        {
RK>            cCachedFile * fl = new cCachedFile();

cCachedFile - это что?

RK>            _metaFile.read((char *) fl, sizeof(cCachedFile));
RK>            if (_metaFile.gcount() == 0)
RK>            {
RK>                delete fl;
RK>                break;
RK>            }
RK>            else
RK>                _listFiles.push_back(fl);
RK>        }
RK>    }
RK>    else // иначе просто создание файла
RK>        _metaFile.open(_metaFileName.c_str(), ios::binary | ios::trunc | ios::out);

и это зачем?

RK>    _metaFile.close();
RK>}

RK>void cCacher::Memory2DB()
RK>{
RK>    SetCurrentDirectory(_rootDir.c_str());

SetCurrentDirectory туда показывает?

RK>    _metaFile.open(_metaFileName.c_str(), ios::binary | ios::trunc | ios::out);

RK>    for (int i = 0; i < _listFiles.size(); i++)
RK>    {
RK>        cCachedFile * fl = _listFiles.at(i);
RK>        _metaFile.write((char *) fl, sizeof(cCachedFile));
RK>    }

RK>    _metaFile.flush();
RK>    _metaFile.close();

RK>
Re[10]: std::string и fstream
От: R1K0 Россия  
Дата: 02.09.09 11:32
Оценка:
Здравствуйте, abrec, Вы писали:


A>cCachedFile — это что?


class cCachedFile
{
    public:
        char    header[1024];
        char    url[256];
        char    fileName[256];
        char    pathToFile[256];
        UINT    entryID;
        UINT    sessionID;
        ULONGLONG fileSize;
        BOOL    wasDownloaded;
};



RK>>// иначе просто создание файла


A>и это зачем?


Гхм. Ну на тот момент это казалось логичным. А вообще от этого не жарко ни холодно никому.

A>SetCurrentDirectory туда показывает?


Как раз на ту папку где лежит необходимый мне файл. Проверял.
Re: std::string и fstream
От: vvv104  
Дата: 02.09.09 12:09
Оценка:
Здравствуйте, R1K0, Вы писали:

RK>Всем привет. Может я туплю, но почему-то проблема со строками и чтением их из файла.


RK>Вот код записи в файл:


RK>
RK>        SetCurrentDirectory(_rootDir.c_str());
RK>    _metaFile.open(_metaFileName.c_str(), ios::binary | ios::app | ios::out);
RK>    _metaFile.write((char *) record_, sizeof(cCachedFile));
RK>    _metaFile.close();
RK>


Извините, вопрос не по теме. Замечено наличие людей любящих символ подчеркивания в именах переменных, типов и т. д. Причем доходит до маразма — начинают вставлять 2 подряд символа подчеркивания, в начале имени, в конце имени или в двух сторон? Как вы например объясните разницу _metaFile и record_. Почему в одном случае так, а в другом эдак?

ИМХО нужно придерживаться какой-то стилистики иначе код читать просто раздражает .
Re[10]: std::string и fstream
От: abrec Россия  
Дата: 02.09.09 12:47
Оценка:
Здравствуйте, abrec, Вы писали:

A>Здравствуйте, R1K0, Вы писали:


RK>>
RK>>void cCacher::DB2Memory()
RK>>{
RK>>    if (FileExists(_metaFileName.c_str())) // файл есть и его можно посмотреть
RK>>    {
RK>>        _metaFile.open(_metaFileName.c_str(), ios::binary | ios::in | ios::app);

A>зачем ios::app на чтении?

RK>>        _metaFile.seekg(ios_base::beg);

A>и тогда это

RK>>        while (! _metaFile.eof())
RK>>        {
RK>>            cCachedFile * fl = new cCachedFile();

A>cCachedFile - это что?

RK>>            _metaFile.read((char *) fl, sizeof(cCachedFile));
RK>>            if (_metaFile.gcount() == 0)
RK>>            {
RK>>                delete fl;
RK>>                break;
RK>>            }
RK>>            else
RK>>                _listFiles.push_back(fl);
RK>>        }
RK>>    }
RK>>    else // иначе просто создание файла
RK>>        _metaFile.open(_metaFileName.c_str(), ios::binary | ios::trunc | ios::out);

A>и это зачем?

RK>>    _metaFile.close();
RK>>}

RK>>void cCacher::Memory2DB()
RK>>{
RK>>    SetCurrentDirectory(_rootDir.c_str());

A>SetCurrentDirectory туда показывает?

RK>>    _metaFile.open(_metaFileName.c_str(), ios::binary | ios::trunc | ios::out);

RK>>    for (int i = 0; i < _listFiles.size(); i++)
RK>>    {
RK>>        cCachedFile * fl = _listFiles.at(i);
RK>>        _metaFile.write((char *) fl, sizeof(cCachedFile));
RK>>    }

RK>>    _metaFile.flush();
RK>>    _metaFile.close();

RK>>


надо _metaFile.clear() — чистить в частночти бад флаг eof
Re[2]: std::string и fstream
От: R1K0 Россия  
Дата: 02.09.09 13:16
Оценка:
Здравствуйте, vvv104, Вы писали:

V>Извините, вопрос не по теме. Замечено наличие людей любящих символ подчеркивания в именах переменных, типов и т. д. Причем доходит до маразма — начинают вставлять 2 подряд символа подчеркивания, в начале имени, в конце имени или в двух сторон? Как вы например объясните разницу _metaFile и record_. Почему в одном случае так, а в другом эдак?


V>ИМХО нужно придерживаться какой-то стилистики иначе код читать просто раздражает .


Так я и придерживаюсь
переменная типа _nameOfVar — private атрибут класса
переменная типа nameOfVar_ — входной параметр метода

и так всегда
Re[11]: std::string и fstream
От: R1K0 Россия  
Дата: 02.09.09 13:33
Оценка:
Здравствуйте, abrec, Вы писали:

A>надо _metaFile.clear() — чистить в частночти бад флаг eof


Большое тебе спасибо
Все дело было именно в этом clear()
Re: std::string и fstream
От: dcb-BanDos Россия  
Дата: 02.09.09 13:40
Оценка:
RK>Скажите, пожалуйста, что тут не так, ибо когда файл считан в vector, то поля url и pathToFile содержат мусор, тогда как все все остальные (включая fileName) содержат именно то, что должны.

конечно не так, нельзя так string сериализовать, используй boost::serialization либо operator<<, operator>>
Ничто не ограничивает полет мысли программиста так, как компилятор.
Re: std::string и fstream
От: SharpC  
Дата: 05.09.09 22:36
Оценка:
Здравствуйте, R1K0, Вы писали:

RK>Скажите, пожалуйста, что тут не так, ибо когда файл считан в vector, то поля url и pathToFile содержат мусор, тогда как все все остальные (включая fileName) содержат именно то, что должны.


В некоторых реализациях STL (например, от Microsoft), если строка короче некоторого количества символов (у MS это 16), то эти символы хранятся в самой структуре, а не по указателю.

_BUF_SIZE = 16 / sizeof (_Elem) < 1 ? 1 : 16 / sizeof(_Elem)

union _Bxty
{    // storage for small buffer or pointer to larger one
    _Elem _Buf[_BUF_SIZE];
    _Elem *_Ptr;
} _Bx;


Поэтому, видимо, fileName содержит то, что должен, а более длинные url и pathToFile нет.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.