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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не пишет в файл, fstream 
:(
    Опции темы
ColdSpirit
Дата 16.12.2014, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 10.12.2010

Репутация: нет
Всего: 2



Есть файл 123.txt, есть функция readLastLineInFile, которая ищет последнюю строку в этом файле. При вызове этой функции программа отказывается писать в файл. Если ее не вызывать, то пишется все нормально, указывание "ios::in | ios::out" не помогает. В файловых потоках не силен, но есть ощущение, что функция задевает какие-то флаги, которые не разрешают запись

main.cpp
Код

  fstream fsIn("123.txt");
  string str;
  readLastLineInFile(fsIn, str); // после вызова этой строки писать не хочет
  fsIn << "hello world" << endl;


readLastLineInFile - ищет последнюю непустую строку, записывает ее в переменную op
Код

std::streampos readLastLineInFile(std::fstream& fsFile, std::string& op, bool savingPosition)
{    
  char _ch;
  bool _stringFinded = false;
  std::streampos _previousPosition = fsFile.tellg();
  std::streampos _newPos; 

  fsFile.seekg(-1, std::ios::end);
  if((int)fsFile.tellg() <= 1) return 0;

  while (!op.length()) 
  {
    fsFile.get(_ch);
    if (_ch == '\n' && _stringFinded)
    {
      getline(fsFile, op);
      _newPos = fsFile.tellg();
      break;
    }
    else if (_ch != '\n')
    {      
      _stringFinded = true;
      fsFile.seekg(-2, std::ios::cur);
    }
    else 
    {
      fsFile.seekg(-3, std::ios::cur);
    }

  }

  if (savingPosition) fsFile.seekg(_previousPosition, std::ios::beg);

  return _newPos;
}

PM MAIL   Вверх
feodorv
Дата 17.12.2014, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(ColdSpirit @  16.12.2014,  20:55 Найти цитируемый пост)
программа отказывается писать в файл

То есть попытка записи приводит к ошибке? Какой её код?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
ColdSpirit
Дата 17.12.2014, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 10.12.2010

Репутация: нет
Всего: 2



feodorv, нету ошибки, программа выполняется нормально, но после этого в файле изменений нету

Добавлено через 4 минуты и 12 секунд
Если закрыть и потом открыть файл, то всё записывается.

main
Код

  fstream fsIn("123.txt");
  string str;
  streampos pos = readLastLineInFile(fsIn, str);
  fsIn.close();

  fsIn.open("123.txt");
  fsIn.seekg(pos);
  fsIn << "hello world" << endl;

PM MAIL   Вверх
ColdSpirit
Дата 17.12.2014, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 10.12.2010

Репутация: нет
Всего: 2



написал функцию вывода флагов
Код

void coutBits(std::fstream& fsFile)
{
  std::cout << "good: " << fsFile.good() << ", eof: " << fsFile.eof() << ", fail: " << fsFile.fail() << ", bad: " << fsFile.bad() << std::endl;
}



Код

coutBits(fsIn); // выдает 1, 0, 0, 0 (all good)
fsIn << "hello world" << endl;
coutBits(fsIn); // 0, 0, 1, 1 (fail & bad)


не понимаю почему так
PM MAIL   Вверх
Vasya
Дата 17.12.2014, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 5.7.2003

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



Такое чувство, что вы где-то открыли монопольный доступ на чтение, потом в другом месте открыли доступ на запись. Когда закрываете файл, освобождается какой-то ресурс и запись становится возможной. Поэтому, чтобы разобраться в вашем приколе, нужно больше кода для анализа. Например, надо понять, как и где инициализируется fsFile.

Это сообщение отредактировал(а) Vasya - 17.12.2014, 22:19
PM MAIL   Вверх
ColdSpirit
Дата 17.12.2014, 22:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 10.12.2010

Репутация: нет
Всего: 2



Цитата(Vasya @  17.12.2014,  22:18 Найти цитируемый пост)
потом в другом месте открыли доступ на запись

В другом внутри программы или системы?

Цитата(Vasya @  17.12.2014,  22:18 Найти цитируемый пост)
Например, надо понять, как и где инициализируется fsFile

fsFile - это ссылка-параметр функции, читающей последнюю строку. Я открываю fsIn в main.cpp и передаю его ссылкой в функцию, чтобы она делала с ним что пожелает.
Во время выполнения функции вроде ничего таинственного не происходит - перевод каретки и чтение строк и символов. Ее код я приводил в 1м посте.

Добавлено через 1 минуту и 51 секунду
Пробовал без передачи по ссылке (встраивал код функции в main.cpp) - ничего не изменилось
PM MAIL   Вверх
Vasya
Дата 18.12.2014, 08:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 5.7.2003

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



Я так понимаю, что после tellg() перед началом записи нужно сделать seekg()

Это сообщение отредактировал(а) Vasya - 18.12.2014, 08:58
PM MAIL   Вверх
ColdSpirit
Дата 18.12.2014, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 10.12.2010

Репутация: нет
Всего: 2



Vasya, с закрытием файла я так и делал, привел пример повыше, но без закрытия это бессмысленно, потому что функция сама перемещает каретку куда надо
PM MAIL   Вверх
Vasya
Дата 18.12.2014, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 5.7.2003

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



Код


  fsFile.seekg(-1, std::ios::end);
  if((int)fsFile.tellg() <= 1) return 0;



Код

 if (_ch == '\n' && _stringFinded)
    {
      getline(fsFile, op);
      _newPos = fsFile.tellg();
      break;
    }


tellg() есть, сразу выходим, seekg() - a нет в одном случае, во втором seekg() будет при savingposition = true, а его при вызове нет

Это сообщение отредактировал(а) Vasya - 18.12.2014, 14:40
PM MAIL   Вверх
ColdSpirit
Дата 18.12.2014, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 10.12.2010

Репутация: нет
Всего: 2



Vasya, выходим из цикла, а после вот что
Код

  return _newPos;


Добавлено через 2 минуты и 1 секунду
Но это ничего не говорит о том, почему флаги ошибок задействуются при записи
PM MAIL   Вверх
Vasya
Дата 18.12.2014, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 5.7.2003

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



И что мы с этим делаем? Ничего! По крайней мере я не вижу. Во втором привере вы все же делаете seek() , и все записывается.
Одним словом, перед записью после tellg нужно сделать seekg. 
А у меня флаги ошибок не задействовались. 
PM MAIL   Вверх
ColdSpirit
Дата 18.12.2014, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 10.12.2010

Репутация: нет
Всего: 2



Написал перед командой записи:
Код

fsIn.seekg(fsIn.tellg());

всё работает! Но я не понимаю почему - эта запись бессмысленна))
Эта команда ничего не делает

Добавлено через 7 минут и 41 секунду
Я не делал seekg() лишний раз в функции, потому что за меня его делает getline(), он автоматически переводит курсор в конец строки, эту позицию я как раз записываю в _newPos и возвращаю

Это сообщение отредактировал(а) ColdSpirit - 18.12.2014, 15:54
PM MAIL   Вверх
Vasya
Дата 18.12.2014, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 72
Регистрация: 5.7.2003

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



Внутри стрима один указатель на объект для работы с записью и для работы с чтением. После теллг  указатель указывает на объект для чтения, который писать не могет. Сикг менят ситуацию. Что-то в этом роде
PM MAIL   Вверх
ColdSpirit
Дата 18.12.2014, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 10.12.2010

Репутация: нет
Всего: 2



Vasya, мне кажется я понял - getline() работает с ifstream, переводит указатель внутри него, а я после этого должен поставить на ofstream. Так?
seekg всегда ставит указатель на ofstream или есть какие-то особенности?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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