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

вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец? - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
22.02.2010, 11:33     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец? #1
Друзья!
То есть написана программка. С клавы вводится ОДИН символ и он запихивается в файл.
А потом этот файл с помощью функции fread считывается обратно в переменную.
Это реализовано в цикле, условие выхода из которого- счётчик считанных байтов достиг конца файла

Но после первого считывания счётчик байтов не достигает конца файла!
Почему? Загадка. Файл имеет размер равный 1, содержит на самом деле один символ (смотрено в hex редакторе), по идее ьон должен считаться и всё, конец цикла

Но то ли функция fread не передвигает счётчик, то ли feof возвращает непрпавильное значение, но мы имеем второе считывание. В чём тут дело?

Эту идею можно и по другому реализовать, но хотелось бы разобраться именно в этом вопросе. Спасибо.
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
#include <stdio.h>
int main() {
 
 char simvol;
 int i;
 FILE* f;
 
 //Вводим символ 
 printf ("vvedi odin simvol ");
 scanf ("%c", &simvol);
 
 //Теперь запихаем этот символ в файл
 if (!(f= fopen ("fail","wb"))) {
  printf ("fail ne otkrit\n");
  getchar ();
 } 
 printf ("zapisanni simvol est %c\n", fputc (simvol, f));
 getchar ();
 fclose (f);
 
 
 
 //а теперь попробуем считать. Символ будет считываться 2 раза!
 if (!(f= fopen ("fail","rb"))) {
  printf ("fail ne otkrit\n");
  getchar ();
 } 
 
 //непосредственно считывание
 i= 0;
 while(!feof(f)) {
  fread(&simvol, 1, 1, f);
  i++;
  printf("i= %d\n", i);
 }
 printf("kak vidim, i== 2");
 fclose(f);
 getchar ();
 return 0;
}
Добавлено через 3 минуты
Прошу прощения, в заголовке надо исправить fputc на fread
Товарищи модераторы, исправьте, пожалуйста. Спасибо.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.02.2010, 11:33     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец?
Посмотрите здесь:

Функция getc (FILE*) при первом вызве считывает НЕ ПЕРВЫЙ символ файла.Почему? C++
есть указатель на конец файла и он самоинициализируется, но не в месте объявления, а когда учавствует в условии. Почему так? C++
Повреждена куча при работе с динам. памятью. Почему? Как исправить? C++
ошибок в компиляции нет, а при работе выходит ошибка, почему? C++
C++ Почему delete не устанавливает автоматически указатель в NULL?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
лендер
46 / 46 / 2
Регистрация: 12.01.2010
Сообщений: 183
22.02.2010, 12:04     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец? #2
попробуй заменить
C
1
2
3
4
5
 while(!feof(f)) {
  fread(&simvol, 1, 1, f);
  i++;
  printf("i= %d\n", i);
 }
на
C
1
2
3
4
5
6
while(!feof(f)) {
  fread(&simvol, 1, 1, f);
if(feof(f)) break;
  i++;
  printf("i= %d\n", i);
 }
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
22.02.2010, 12:45  [ТС]     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец? #3
Заменил, сработало.
Но в чём прикол, я понять не могу.
Почему функция feof () в одном случае возвращает 0, а в другом 1?

Ничё не могу понять. Хотелось бы услышать ответ знающих людей.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
22.02.2010, 13:07     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец? #4
Цитата Сообщение от kravam Посмотреть сообщение
Но в чём прикол, я понять не могу.
Да всё правильно.
1. проверяется условие ( !feof(f) )
2. читается символ fread(&simvol, 1, 1, f); вот тут, если неудачно, feof вернула бы 1
3. i++ и тд. - не должно выполняться, если достигнут конец файла...
Просто цикл неправильно организован
C
1
2
3
4
5
...
int ch;
while ( ( ch = fgetc(f) ) != EOF ){
  ...
}
или
C
1
2
3
...
while ( fread(&simvol, 1, 1, f) ){
  ...
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
22.02.2010, 13:22  [ТС]     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец? #5
C++
1
2
3
4
5
while(!feof(f)) {
  fread(&simvol, 1, 1, f);
  i++;
  printf("i= %d\n", i);
 }
Тут что неправильно?
Давай пошагово. Итак, в файле один символ

1) feof возвращает 0 (так?)
2) зашли в тело цикла считали один символ
3) инкременировали i
4) пошли на проверку условия

...Теперь отвлекёмся и зададимся вопросом:
должно ли условие выполняться?
Или уж совсем просто: что должна вернуть функция feof,
учитывая, что в файле ОДИН симол и тот считан?
Ну, наверное единицу, угу?

Но ничё подобного, возаращается НОЛЬ, (наблюдаем выполнение тела цикла
второй раз).

Вопрос: почему feof возвращает ноль?

Добавлено через 2 минуты
P. S. Я понимаю, что если сделать, как говорит лендер, то некотрый результат будет достигнут. Некотоый, но не желательный. Ибо заявленый результат: показать, что непрпавильно в моём коде.
спасибо за понимание.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
22.02.2010, 13:40     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец? #6
Цитата Сообщение от kravam Посмотреть сообщение
Вопрос: почему feof возвращает ноль?
потому, что feof() вернёт 1 не после чтения первого (и единственного) байта, а после попытки чтения второго (несуществующего). Сначала нужно выполнить операцию (чтения в данном случае), а потом её результаты проверять. У Вас же наоборот получается.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
22.02.2010, 13:57  [ТС]     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец? #7
Всё понятно! И можно было бы подумать о закрытии темы, если бы Ваши слова не вступали в противоречие с реальностью. Вот код Лендера.
C++
1
2
3
4
5
6
while(!feof(f)) {
  fread(&simvol, 1, 1, f);
  if(feof(f)) break;
  i++;
  printf("i= %d\n", i);
 }
Судя по тому, что Вы сказали, feof после первого считывания должна что вернутть? 0! Поскольку попытки чтения второго (несуществующего) просто нет!

Но щас она возвращает 1!

Как быть?
То, что Вы говорите, объясняет мой код, но АБСОЛЮТНО не объясняет код Лендера. А ведь у нас различия-то минимальны! Он вызывает feof (второй раз) СРАЗУ после чтения символа, а я... так и я тоже СРАЗУ, просто делаю это в условии, а он в теле цикла. Всё! (инкременацию i опускаю пока.)

Добавлено через 1 минуту
И извините, при таком раскладе я, при всём уважении к Вам, крайне не удовлетворён объяснением.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
22.02.2010, 14:06     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец? #8
Цитата Сообщение от kravam Посмотреть сообщение
C++
1
2
fread(&simvol, 1, 1, f); 
if(feof(f)) break;
Цитата Сообщение от easybudda Посмотреть сообщение
Сначала нужно выполнить операцию (чтения в данном случае), а потом её результаты проверять.
После чтения первого символа if(feof(f)) возвращает 0, цикл отрабатывает. После попытки чтения второго if(feof(f)) вернёт 1 и выполнится команда break; При таком подходе можно вообще вот так:
C
1
2
3
4
5
6
while(1) {
  fread(&simvol, 1, 1, f);
  if(feof(f)) break;
  i++;
  printf("i= %d\n", i);
 }
сделать и тоже будет работать.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
22.02.2010, 14:30  [ТС]     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец? #9
Ага. То есть если вызов fread неудачен, то feof вернёт 1
Что ж, это объясняет многое, но не всё.

Снова обратимся к моему коду и опять протрассируем его пошагово с учётом вновь полученых знаний.
C++
1
2
3
4
5
while(!feof(f)) {
  fread(&simvol, 1, 1, f);
  i++;
  printf("i= %d\n", i);
 }
1) feof возвращает 0 (так?)
2) зашли в тело цикла считали один символ
3) инкременировали i
4) пошли на проверку условия
5) условие выполняется потому, что предыдущее считывание было удачным

...И вот тут стоп. Я понимаю, почему выполняется условие, Вы объяснили. (Предыдущий вызов fread был удачным, вот оно и выполняется)

А темерь внимание, вопрос, которого мы не касались:


6) зашли в тело цикла удачно считали считанный уже символ.

Почему? Он ведь уже считан? По идее вызов fread должен завершиться неудачно.
Но нет, символ считывается. Почему?
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
22.02.2010, 14:34     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец? #10
Цитата Сообщение от kravam Посмотреть сообщение
Почему? Он ведь уже считан? По идее вызов fread должен завершиться неудачно.
Но нет, символ считывается. Почему?
Вот именно уже считан. И после неудачной попытки чтения следующего просто не изменяется.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
22.02.2010, 15:12  [ТС]     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец? #11
Ну вот теперь всё понятно и всё просто. Учитываем, что feof возвращает значение в зависимости от значения, возвращённого fread, а я не знал этого. Думал, считался единственный символ и feof вернёт не ноль, но я ошибался. Большое спасибо!
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
09.11.2012, 12:26     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец? #12
kravam, вообще - то как бы делается вот так
C
1
2
3
4
5
6
7
while (expression) {
    ret = fread(bufer, size, nmemb, FILE);
    if (ret == EOF)
        break;
    if ( ret != nmemb )
        work_exeption(...);
}
Croessmah
09.11.2012, 12:28
  #13

Не по теме:

Цитата Сообщение от alkagolik Посмотреть сообщение
kravam, вообще - то как бы делается вот так
теме почти 3 года...

alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
09.11.2012, 13:00     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец? #14
Croessmah, да. она просто сегодня упомянулась в соседней теме, да и не раскрыт вопрос. Считаю что поставил в нем точку. ИМХО

Не по теме:

считай меня некропостером)))

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.11.2012, 14:54     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец?
Еще ссылки по теме:

Конец файла при потоковом считывании C++
C++ Аналог !foef, или как найти конец строки при работе с файлом
Почему выдает ошибку при работе с большим файлом, напишите как исправить ? C++

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

Или воспользуйтесь поиском по форуму:
kravam
09.11.2012, 14:54  [ТС]     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец?
  #15

Не по теме:

А я люблю добросовестных парней, которым по фигу, как их назовут- некропостерами или ещё как-то. Уж ни-то точно 100 раз подумают, прежде чем тему новую скропать, уже за одно это им спасибо.

Yandex
Объявления
09.11.2012, 14:54     вопрос к спецам: почему функция fputc при работе не устанавливает счётчик файла в конец?
Ответ Создать тему
Опции темы

Текущее время: 01:30. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru