Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Как правильно использовать fgets?


Автор: AxNe0 11.5.2006, 13:20
Как можно прочесть первую строку открытого с помощью fopen файла?
 smile  
 

Автор: Romikgy 11.5.2006, 13:42
Код

/* fgets example */ 

#include <string.h>
#include <stdio.h>

int main(void)
{
   FILE *stream;
   char string[] = "This is a test";
   char msg[20];
   /* open a file for update */
   stream = fopen("DUMMY.FIL", "w+");
   /* write a string into the file */
   fwrite(string, strlen(string), 1, stream);
   /* seek to the start of the file */
   fseek(stream, 0, SEEK_SET);
   /* read a string from the file */
   fgets(msg, strlen(string)+1, stream);
   /* display the string */
   printf("%s", msg);
   fclose(stream);
   return 0;
}
 

Автор: AxNe0 11.5.2006, 15:14
Romikgy, а если заранее длина строки неизвестна? 

Автор: likehood 11.5.2006, 15:42
Вторым параметром fgets задается максимальный размер строки, т.е. длина массива string. Эта длина должна быть заведомо больше самой длинной строки в файле. 

Автор: gepard 11.5.2006, 16:02
Значит её сначала надо посчитать smile
Считываешь по байтам, когда встречаешь конец строки - обрываешь увелечение счётчика и получаешь длинну. 

Автор: bsa 11.5.2006, 17:10
Код

char *fgets(char *s, int size, FILE *stream);

fgets() reads in at most one less than size characters from stream  and
       stores  them  into  the buffer pointed to by s.  Reading stops after an
       EOF or a newline.  If a newline is read, it is stored into the  buffer.
       A '\0' is stored after the last character in the buffer.

Таким образом, если в конце прочитанной строки отсутствует символ конца строки ('\n'), то это говорит:
  а) строка в файле длиннее, чем выделенный под нее буфер
  б) достигнут конец файла (это условие можно проверить с помощью feof(stream) )
Поэтому, чтобы прочитать строку любой длины из файла, надо:

1. выделить буфер s размером n=N знаков: s = (char*)malloc( n );
2. объявить переменную переменной int d = 0;
3. прочитать в s + d не более (n-d) символов
4. d += strlen(s);
5. ecли feof(fd) != 0, то переход на п. 7
6. если s[ d - 1] != '\n'
6.1. n += N;
6.2. увеличить объем буфера: s = (char*)realloc( s, n )
6.3. перейти на п. 3
7. если feof(fd) != 0, то d = 0
8. переход на п. 3
9. конец.

В пункте 7 имеем полностью прочитанную строку. Все, кроме последней быть может, будут заканчиваться на символ конца строки '\n'. 

Автор: nworm 11.5.2006, 17:42
Если пошли такие проблемы, то можно просто писать свою функцию (чтобы от длины строки не зависела). А за основу взять код функции fgets из стандартной библиотеки.  

Автор: AxNe0 11.5.2006, 21:59
Написал:
Код

    FILE *file;
         char *loadstring=new char[100];
    char *msg;    
         file = fopen(filename, "r");
    if (file!= 0 )
    {
        int LineLength=0;
        fseek(file, 0, SEEK_SET);
        while (1)
        {
            char ch = fgetc(file);
            if ( ch == '\n' ||  ch == '\r' ) break;
            LineLength++;
        };
    
        if (LineLength!=0)
        {
            fseek(file, 0, SEEK_SET);
            char *m = new CHAR[LineLength];
            fgets(m, LineLength, file);
            strcpy(msg,m);
        };
    };
    fclose(file);

Не работает. Почему?  smile  

Автор: Dithur 11.5.2006, 22:30
Функция подсчёта длины списка, думаю можно идею использовать для подсчёта длины первой строки файла, если чуть-чуть подправить: 

Код

int lstlen(CHR_LST *left, CHR_LST *right)
{
    int len=0;
    CHR_LST *tmp=left; 
    while(tmp!=NULL&&tmp!=right->next)
    {
    len++;
    tmp=tmp->next;
    }
    return len;
}



Честно признаюсь код сдул месяц назад с кого-то задачника, по-моему с Тарасова, может пригодится smile 

Автор: Romikgy 12.5.2006, 09:00
AxNe0, если неизвестно , тогда счтитывай по символьно , до перевода строки 

Автор: AxNe0 12.5.2006, 11:08
Кто-нибудь знает, где можно найти более-менее понятное описание функций из <string.h>? До использовал ObjectPascal, а тут функции немного по-другому называются...  smile  

Автор: bsa 12.5.2006, 11:20
Код
char * readline(FILE * f) {
     int d = 0;
     char * s = NULL;
     char * r;
     while( !feof(f) ) {
          s = realloc( s, d + 128);
          r = fgets(s + d, 128, f);
          if ( r == s ) {
                d = strlen(s);
                if ( ( d == 0 ) || ( s[d-1] == '\n' ) ) { //сомнительная строка. корректность выполнения зависит от конкретного компилятора и оптимизации
                      s = (char*)realloc(s, d + 1 );
                      break;
                }
          }
     }
     return s;
}


Добавлено @ 11:25 
Цитата(AxNe0 @ 12.5.2006,  11:08)
Кто-нибудь знает, где можно найти более-менее понятное описание функций из <string.h>? До использовал ObjectPascal, а тут функции немного по-другому называются...  smile

http://www.google.com/search?hs=en7&hl=ru&rls=ru&q=string.h&btnG=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA&lr= 

Автор: AxNe0 12.5.2006, 23:39
Всем спасибо! Учел.
Код

char * o_file(char *filename)
{
        char *result="";
        FILE *f;
        f = fopen(filename, "r");
        if (f!= 0 )
            {
            //int LineLength=0;
            char ch;
            fseek(f, 0, SEEK_SET);
            while (!feof(f) && ch != '\n' &&  ch != '\r')
                {
                ch = fgetc(f);
                if ( ch != '\n' &&  ch != '\r' && !feof(f)) result+=ch;
                };
            return(result);
            }
        else 
        {
            AfxMessageBox("Файл не найден",MB_OK | MB_ICONSTOP,0);
            return("Файл не найден");
        };
        fclose(f);
};

Результат функции должен отображаться на CStatic, но отображается вместо латинских букв такая штука: user posted image
Как можно поправить ситуацию?  smile  

Автор: Romikgy 13.5.2006, 08:51
Цитата(AxNe0 @  12.5.2006,  22:39 Найти цитируемый пост)
 отображаться на CStatic

покажи код вывода в цстатик? 

Автор: AxNe0 13.5.2006, 16:04
Вот весь код, относящийся к CStatic
Код

         MyStatic = new CStatic();
    if (MyStatic!=NULL) MyStatic->Create(o_file(filename),WS_CHILD|WS_VISIBLE|SS_CENTER,    rcstat,this);
    MyStatic->CenterWindow(this);
 

Автор: AxNe0 15.5.2006, 00:46
Отбой тревоги!  smile  понял, надо было заменить строки
Код

    char *result="";
...
               if ( ch != '\n' &&  ch != '\r' && !feof(f)) result+=ch;

на
Код

    char *result=new char[];
...
              if ( ch != '\n' &&  ch != '\r' && !feof(f)) result[i]=ch;

соответственно.
 smile  

Автор: Kosya4ok 18.12.2007, 19:07
я так понимаю что char * fgets ( char * str, int num, FILE * stream ) второй аргумент отвечает за число симовлом которые будут прочитаны и записаны в char *str?
Если так то странно получается. Создал файл

1345f;dfjag
2sdhsg
3sgh

и говорю 

Код

char buffer [100];
while ( !feof(pFile) ) 
     {
       fgets (buffer , 2 , pFile); 
       fputs (buffer , stdout);
     }

 
так мне почему то все равно выводит все символы записанные в фале. Как ограничить тогда колиство выводимы символов?

Автор: nworm 18.12.2007, 23:46
Ну. не знаю. Может
Цитата

Код

while ( !feof(pFile) ) 


убрать?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)