Найти строку с наибольшей длиной (Си)
У меня несколько вопросов по этой задаче: как определить что закончилась строка и началась другая строка? как определить конец файла? и вообще что такое строчка (это набор символов без пробелов или пробелы там могут встречаться)?
вот конец файла определяется if (feof(f)) { // blah blah... }, где f дескриптор открытого файла.
строка, это массив символов. оканчивается либо символом \0, либо последовательностью \r\n (в Windows), либо \n (в Linux)
в общем, по поводу решения задачи.
читаешь по 1 символу из файла пока не встретишь \n (складываешь в массив типа char), в любом случае это будет конец строки. запоминаешь символ, с которого началась строка (его индекс в файле - ftell тебе поможет). определяешь длину массива, и если она больше предыдущей длины (сохранённой у тебя в переменной какой-нибудь), обновляешь сохранённую длину, и индекс начала строки. и так до конца файла.
в общем, когда
ты пройдешь весь файл: смотришь индекс символа, с которого началась самая длинная строка, делаешь fseek на этот индекс и читаешь снова до \n - вот тебе получится самая длинная строка в файле.
PS: на всякий случай, сделал тебе все имена функций ссылками на документацию по этим функциям. Удачи!
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) )
{
....
}
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);
}
}
работает... :)
Найти строку с наибольшей длиной (Си)
Или может название ветки не заметил?;)имхо код тяжеловат будет
1. Какой функцией можно считывать посымвольно из файла?
2. И как мне про окончании проверки одной строки перейти на другую?
2. строки никак не выделяются в файле, просто в последовательности символов встречаются '\n', которые обозначают переход на новую строку (это символ используют, например блокнот и выводит символы на разных строках)
считываю я посимвольно из файла, до тех пор пока не встретится "\n" и считаю длину этой строки, а как мне потом перейти на другую строчку и начать там считать символы, я вот что не могу понять как делать.
и ещё:
какую мне брать размерность массива? ведь строка (т.е. до "\n" может быть сколь угодно длинной или у неё все же есть ограничения по длине)?
Ты как длину строки считаешь? Переменная у тебя для этого есть. Вот и обнуляй её каждый раз, когда '\n' встречается и заново считай. Размерность массива бери произвольную, но следи, чтобы не было переполнения. Можешь включить контроль переполнения - если встретилась строка длинная (не помещается в массив), то записать все символы, которые помещаются, а остальные игнорировать. Ограничений на длину строки нет.
После прохождения всего файла с помощью fseek переходишь на начало строки с максимальной длиной, и тогода уже делай что хочешь - на печать выводи, в массив запоминай (длину массива ты теперь будешь знать - воспользуешься malloc).
Суть то не меняется...
Да ну?! ;) Уверен?
#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();
}
Подскажите что не так, может я как-то не правильно использую некоторые функции или может я вообще ничего не понял:(
Помогите пожалуйста разобраться.
В разных случаях конец строки понимается по-разному: некоторые программы понимают под концом строки \n, некоторые - последовательность \r\n, или, говоря шестнадцатеричным языком, 0D 0A.
Разбираться не стал, грабли есть конечно. Вот один из вариантов, более лаконичный:
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;
}
Подскажите что не так, может я как-то не правильно использую некоторые функции или может я вообще ничего не понял:(
Помогите пожалуйста разобраться.
Ну, если тебе хочется узнать, где ошибки в ТВОЕМ коде, то смотри:
#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 (или задать предварительно с).
Это что касается ошибок, есть конечно замечания (мысли) по реализации, но это уже флуд...........