Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Найти строку с наибольшей длиной (Си)

16K
17 августа 2007 года
Draconit
39 / / 10.08.2007
Задача: Дан текстовый файл f. Получить самую длинную строку файла. Если в файле имеется несколько строк с наибольшей длиной, то получить одну из них.

У меня несколько вопросов по этой задаче: как определить что закончилась строка и началась другая строка? как определить конец файла? и вообще что такое строчка (это набор символов без пробелов или пробелы там могут встречаться)?
92
17 августа 2007 года
Тень Пса
2.2K / / 19.10.2006
fopen знаешь?

вот конец файла определяется if (feof(f)) { // blah blah... }, где f дескриптор открытого файла.

строка, это массив символов. оканчивается либо символом \0, либо последовательностью \r\n (в Windows), либо \n (в Linux)

в общем, по поводу решения задачи.

читаешь по 1 символу из файла пока не встретишь \n (складываешь в массив типа char), в любом случае это будет конец строки. запоминаешь символ, с которого началась строка (его индекс в файле - ftell тебе поможет). определяешь длину массива, и если она больше предыдущей длины (сохранённой у тебя в переменной какой-нибудь), обновляешь сохранённую длину, и индекс начала строки. и так до конца файла.

в общем, когда
ты пройдешь весь файл: смотришь индекс символа, с которого началась самая длинная строка, делаешь fseek на этот индекс и читаешь снова до \n - вот тебе получится самая длинная строка в файле.

PS: на всякий случай, сделал тебе все имена функций ссылками на документацию по этим функциям. Удачи!
2.0K
17 августа 2007 года
WidowMaker
212 / / 05.04.2005
имхо, если заранее известно, что строки не будут превышать определенной длины, то можно юзать fgets с буфером этой длины. Например так:
Код:
...
const int maxBuf=256;
char buf[256];
long pos=0;
int maxlen=0;
int ln=0;
FILE *file=fopen(filename,"r");
while( fgets(buf,maxBuf,file) )
{
....
}
92
17 августа 2007 года
Тень Пса
2.2K / / 19.10.2006
если известно.
22K
17 августа 2007 года
Pastor
43 / / 16.05.2007
Код:
HANDLE hFile = INVALID_HANDLE_VALUE;
DWORD lSize = 0, hSize = 0, nRead = 0;
char *buffer = NULL;
HANDLE mainHeap = NULL, processHeap = GetProcessHeap ();

int main(int argc, char *argv){
    __try {
        hFile = CreateFile ("E:\\Documents and Settings\\Pastor\\Мои документы\\test.txt",
                            GENERIC_READ,
                            FILE_SHARE_READ,
                            NULL,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL,
                            NULL);
        if (hFile == INVALID_HANDLE_VALUE) __leave;
        lSize = GetFileSize (hFile, &hSize);
        if (hSize) {
            MessageBox (0, "Шибко большой", 0, 0);
            __leave;
        }
        mainHeap = HeapCreate (HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE, 0, 0);
        if (!mainHeap) mainHeap = processHeap;
        buffer = (char *)HeapAlloc (mainHeap, HEAP_ZERO_MEMORY, lSize+1);
        ReadFile (hFile, buffer, lSize, &nRead, NULL);
        if (nRead != lSize) {
           MessageBox (0, "Где-то ошибка", 0, 0);
            __leave;
        }
        *(buffer+lSize+1) = 0;
        int __w64 pos = 0, maxSize = 0, curSize = 0, maxPos = 0;
        char *beg = buffer, *maxString = buffer;
        while (*(beg)) {
            if (*(beg++)=='\n') {
                ++pos;
                *(beg-1) = 0;
                if (curSize > maxSize) {
                    maxSize = curSize;
                    maxPos = pos;
                    maxString = beg - curSize;
                }
                curSize = 0;
                continue;
            }
            ++curSize;
        }
        MessageBox (0, maxString, "Максимальная строка", 0);
    } __finally {
        if (hFile != INVALID_HANDLE_VALUE) CloseHandle (hFile);
        if (buffer) HeapFree (mainHeap, HEAP_NO_SERIALIZE, buffer);
        if (mainHeap != processHeap) HeapDestroy (mainHeap);
    }
}

работает... :)
2.0K
17 августа 2007 года
WidowMaker
212 / / 05.04.2005
2Pastor: Ты топ внимательно читал?
Цитата:

Найти строку с наибольшей длиной (Си)


Или может название ветки не заметил?;)имхо код тяжеловат будет

16K
18 августа 2007 года
Draconit
39 / / 10.08.2007
to Тень Пса спасибо, но мне ещё не все понятно:
1. Какой функцией можно считывать посымвольно из файла?
2. И как мне про окончании проверки одной строки перейти на другую?
2.0K
18 августа 2007 года
WidowMaker
212 / / 05.04.2005
1. fgetc
2. строки никак не выделяются в файле, просто в последовательности символов встречаются '\n', которые обозначают переход на новую строку (это символ используют, например блокнот и выводит символы на разных строках)
16K
18 августа 2007 года
Draconit
39 / / 10.08.2007
Это я знаю, что в файле строки никак не выделяются, я вот насчет чего:
считываю я посимвольно из файла, до тех пор пока не встретится "\n" и считаю длину этой строки, а как мне потом перейти на другую строчку и начать там считать символы, я вот что не могу понять как делать.
и ещё:
Цитата: Тень Пса
читаешь по 1 символу из файла пока не встретишь \n (складываешь в массив типа char)!


какую мне брать размерность массива? ведь строка (т.е. до "\n" может быть сколь угодно длинной или у неё все же есть ограничения по длине)?

1.8K
18 августа 2007 года
igor_nf
256 / / 13.12.2006
Цитата: Draconit
считываю я посимвольно из файла, до тех пор пока не встретится "\n" и считаю длину этой строки, а как мне потом перейти на другую строчку и начать там считать символы, я вот что не могу понять как делать?


Ты как длину строки считаешь? Переменная у тебя для этого есть. Вот и обнуляй её каждый раз, когда '\n' встречается и заново считай. Размерность массива бери произвольную, но следи, чтобы не было переполнения. Можешь включить контроль переполнения - если встретилась строка длинная (не помещается в массив), то записать все символы, которые помещаются, а остальные игнорировать. Ограничений на длину строки нет.

263
18 августа 2007 года
koltaviy
816 / / 16.12.2004
Зачем вообще что-то записывать в массив?? Проходишь по строкам - сравниваешь длину текущей строки с максимальной длиной. Если длина больше, запоминаешь новую максимальную длину и начало этой строки.
После прохождения всего файла с помощью fseek переходишь на начало строки с максимальной длиной, и тогода уже делай что хочешь - на печать выводи, в массив запоминай (длину массива ты теперь будешь знать - воспользуешься malloc).
9
18 августа 2007 года
Lerkin
3.0K / / 25.03.2003
Вам бы определиться, что считать строкой в текстовом файле. Может быть требуется разбирать файл на предмет строк, заканчивающейся точкой (.), и уже их считать. А вдруг у меня в текстовом файле все строки без [FONT="Courier New"]\n[/FONT]?
2.0K
18 августа 2007 года
WidowMaker
212 / / 05.04.2005
Цитата: Lerkin
Вам бы определиться, что считать строкой в текстовом файле. Может быть требуется разбирать файл на предмет строк, заканчивающейся точкой (.), и уже их считать. А вдруг у меня в текстовом файле все строки без [FONT=Courier New]\n[/FONT]?


Суть то не меняется...

9
18 августа 2007 года
Lerkin
3.0K / / 25.03.2003
Цитата: WidowMaker
Суть то не меняется...


Да ну?! ;) Уверен?

16K
21 августа 2007 года
Draconit
39 / / 10.08.2007
Вообщем вот что получилось (но не работает):
Код:
#include <math.h>
#include <stdio.h>
#include <conio.h>
#include <io.h>
#include <sys\stat.h>
#include <string.h>
#include <fcntl.h>
FILE *textf;
char c,c1;
int s;
long max,i,p,p1;
void main()
{
 clrscr();
 textf=fopen("f.txt","r");
 max=0;
 s=0;
 while (!feof(textf))
  {
  // s=0;
 /*  while (s!=1)
   {
   p=ftell(textf);
   fscanf(textf,"%c1",&c1);
   s++;
   }*/
   p=ftell(textf);
   fscanf(textf,"%c",&c);
   while (c!='\n')
   { i++; s=0;}
   if (i>max)
    {
     max=i;
     p1=p;
    }
  }
 fseek(textf,0L,p1);
 while (c!='\n')
  {
   fscanf(textf,"%c",&c);
   printf("%c",c);
  }
 getch();
}


Подскажите что не так, может я как-то не правильно использую некоторые функции или может я вообще ничего не понял:(
Помогите пожалуйста разобраться.
16K
22 августа 2007 года
Zbyszek
118 / / 08.08.2007
Я не силён в С, но мне кажется, что нужно сравнивать не с '\n' а с 0Ah. Если я ошибаюсь, исправьте меня, и, пожалуйста, не злитесь:).
350
25 августа 2007 года
cheburator
589 / / 01.06.2006
Цитата: Zbyszek
Я не силён в С, но мне кажется, что нужно сравнивать не с '\n' а с 0Ah. Если я ошибаюсь, исправьте меня, и, пожалуйста, не злитесь:).


В разных случаях конец строки понимается по-разному: некоторые программы понимают под концом строки \n, некоторые - последовательность \r\n, или, говоря шестнадцатеричным языком, 0D 0A.

1.8K
25 августа 2007 года
igor_nf
256 / / 13.12.2006
Цитата: Draconit
Вообщем вот что получилось (но не работает):


Разбираться не стал, грабли есть конечно. Вот один из вариантов, более лаконичный:

Код:
#include <stdio.h>

int main( void ) {

    char ch;
    int currlen;
    int maxlen;
    FILE* fp;

    if (( fp = fopen( "f.txt", "r" )) == NULL ) {
        fprintf( stderr, "Can't open, exiting...\n" );
        exit( 1 );
    }

    for( maxlen = 0; (ch = getc(fp)) != EOF; ++currlen ) {
   
        if( ch == '\n' ) {
            if( maxlen < currlen )
                maxlen = currlen;
        currlen = 0;
        }
    }

    fprintf( stdout, "Максимальная длина строки в файле - %d\n", maxlen );

return 0;
}
2.0K
28 августа 2007 года
WidowMaker
212 / / 05.04.2005
Цитата: Draconit
Вообщем вот что получилось (но не работает):
Подскажите что не так, может я как-то не правильно использую некоторые функции или может я вообще ничего не понял:(
Помогите пожалуйста разобраться.


Ну, если тебе хочется узнать, где ошибки в ТВОЕМ коде, то смотри:

Код:
#include <math.h>
#include <stdio.h>
#include <io.h>
#include <sys\stat.h>
#include <string.h>
#include <fcntl.h>
FILE *textf;
char c,c1;
int s;
long max,i,p,p1;
void main()
{
 textf=fopen("f.txt","r");
 max=0;
 s=0;
 while (!feof(textf))
 {
 
  p=ftell(textf);
  fscanf(textf,"%c",&c);
  while (c!='\n')
  {
   i++; s=0;
   [COLOR=red]fscanf(textf,"%c",&c);
[/COLOR]  }
  if (i>max)
  {
   max=i;
   p1=p;
  }
  i=0;
 }
[COLOR=red] fseek(textf,p1,SEEK_SET);[/COLOR]
[COLOR=red] do
 {
  fscanf(textf,"%c",&c);
  printf("%c",c);
 }
 while (c!='\n');[/COLOR]
}

Для начала программа заходит в безконечный цикл с условием , которое не изменяется в теле цикла. Это наш прочитанны символ с, поэтому добавляем fscanf.
Это раз. Два - ты путаешь порядок параметров в fseek, а что бы этого не было, на будующее, используй константы (SEEK_SET) и смотри внимательней описание прототипов.
Три. Когда ты выводишь строку, цикл ниразу не запускается, т.к. символ с указывает на последний прочитанный символ, нужно изменить форму цикла на do while (или задать предварительно с).

Это что касается ошибок, есть конечно замечания (мысли) по реализации, но это уже флуд...........
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог