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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Запись и чтение текстового файла 
:(
    Опции темы
Bugrimov
Дата 8.11.2012, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Доброе время суток. Нужен совет знающих людей.
Программа создает 2-а файла (one two). Вводимые данные записываются в файл one и потом преобразуя (М), записываются в файл two. Все бы хорошо, но меня смущают две буквы ЯЯ. Я ввожу 5-ть строк, а ЯЯ выводятся 6-й строкой. Подскажите как с этим бороться. Как я представляю это мусор выводимый на экран

Код

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#define n 5

main()
{
char temp[20], ch, s;
int i;
FILE *pf, *pr;
system("chcp 1251 > nul");
     pf = fopen("one.txt", "wt");
     system("cls");

     printf("\n *********************\n");
     printf(" * Ввести 5-ть строк *\n");
     printf(" *********************\n\n");     
for(i=0; i<n; i++)
{
     gets(temp);
     fprintf(pf,"%s\n", temp);
}
     fclose(pf);
     printf("\n Строки записаны в файл 'one.txt'\n");

printf("\n ************************************************************************\n");     
printf(" Поменять строчные 'м' на прописные 'М' и записать в файл 'two.txt'(Y/N): "); scanf("%c", &s);

if(s == 'y' || s == 'Y')
{
     system("cls");
     fflush(stdin);
     printf("\n ******************************");
     printf("\n * Содержимое файла 'two.txt' *");
     printf("\n ******************************\n\n");
     pf = fopen("one.txt", "rt");
     pr = fopen("two.txt", "wt");
     
     while(!feof(pf))
     {
           ch = getc(pf);
           if(ch == 'м')
                 putc('М',pr);
           else
                 putc(ch,pr);
     }
     fclose(pr);
     rewind(pf);
     pr = fopen("two.txt", "rt");
     while(!feof(pr))
     {
           ch = getc(pr);
           putchar(ch);
     }
     fclose(pf);
     fclose(pr);
     getch();
}
else          
return 0;          
}


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


Эксперт
****


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

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



Буквы 'Я' - это символьное представление EOF.
Дело в том, что feof() сработает, только если до этого была попытка чтения за пределами конца файла:
Цитата

Checks whether the end-of-File indicator associated with stream is set, returning a value different from zero if it is.

This indicator is generally set by a previous operation on the stream that attempted to read at or past the end-of-file.

Notice that stream's internal position indicator may point to the end-of-file for the next operation, but still, the end-of-file indicator may not be set until an operation attempts to read at that point.

feof()


Вот представьте себе, что файл two.txt - пустой (нулевой длинны). Что выведет этот код:
Цитата(Bugrimov @  8.11.2012,  21:10 Найти цитируемый пост)
     pr = fopen("two.txt", "rt");
     while(!feof(pr))
     {
           ch = getc(pr);
           putchar(ch);
     }
     fclose(pr);

Сразу после открытия файла (несмотря на то, что он пустой!) feof() не вернёт 1, потому не было попытки чтения, поэтому проваливаемся в тело цикла, где getc(pr) возвращает EOF, которое успешно печатается в виде буквы 'Я'. 

Нужно переделать логику программы, чтобы не печатать EOF.

Это сообщение отредактировал(а) feodorv - 8.11.2012, 22:10


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


Новичок



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

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



Подскажите каким образом построить программу. Я понял, что это из-за feof. 
PM MAIL   Вверх
Riviero
Дата 9.11.2012, 08:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код

     pr = fopen("two.txt", "rt");
     while(!feof(pr))
     {
           ch = getc(pr);
           if (feof(pr))
                break;
           putchar(ch);
     }
     fclose(pr);


Можно так попробовать...

Это сообщение отредактировал(а) Riviero - 9.11.2012, 08:24
PM MAIL   Вверх
feodorv
Дата 9.11.2012, 09:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Bugrimov @  9.11.2012,  05:56 Найти цитируемый пост)
Подскажите каким образом построить программу.

Вариантов масса, самый простой путь - использовать возвращаемое от getc значение:
Цитата

fgetc(), getc() and getchar() return the character read as an unsigned char cast to an int or EOF on end of file or error. 

То есть:
Код

while( (ch = getc(pr)) != EOF )
   ...

А после цикла, если это хоть кому-то интересно, можно провериться на возможную ошибку чтения:
Код

if( ferror(pr) ) ...

так как getc может вернуть EOF не только в случае достижения конца файла.


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


Эксперт
****


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

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



Цитата(feodorv @  9.11.2012,  09:25 Найти цитируемый пост)
while( (ch = getc(pr)) != EOF )

feodorv, у ТС ch объявлен как char, поэтому так проверять нельзя.
В случае русской буквы 'я' программа блогополучно примет ее за конец файла.
если бы ch был интом, тогда бы это работало.

Если же ch объявить интом, то у ТС отвалятся другие части программы.  smile
По-хорошему нужно конечно переписывать всю программулину от начала, но лень матушка.
а по сему,

Bugrimov, 
проще всего в вашем случае сделать как сказал Riviero, 
Цитата(Riviero @  9.11.2012,  08:23 Найти цитируемый пост)
     pr = fopen("two.txt", "rt");
     while(!feof(pr)) for (;;) // можно даже так.
     {
           ch = getc(pr);
           if (feof(pr))
                break;
           putchar(ch);
     }
     fclose(pr);

Ну и второй цикл также

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


Эксперт
****


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

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



Цитата(volatile @  9.11.2012,  19:32 Найти цитируемый пост)
feodorv, у ТС ch объявлен как char, поэтому так проверять нельзя.

Ваша правда, volatile, не доглядел. Вообще, если функция возвращает int, то лучше в этот int и сохранять возвращаемое значение  smile 


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

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

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

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

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


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

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


 




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


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

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