IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

 
 Ответить  Открыть новую тему 
> Файлы (вместо типизированных), с++
сообщение
Сообщение #1


просто человек
******

Группа: Пользователи
Сообщений: 3 641
Пол: Женский
Реальное имя: Юлия

Репутация: -  55  +


есть алгоритм многофазной сортировки, которая работает с файлами. в делфи это был file of integer.
поскольку в с++ абсолютного аналога нет, возник вопрос - что выбрать из имеющихся средств?
Запуталась sad.gif
В чем разница между парами:
fread-fwrite; (для всего подряд?)
fscanf-fprintf; (форматированный ввод/вывод? то есть %d - и будет мне десятичное целое число, как и хочется?)
fgets-fputs; (это вроде для строк.... то есть потом можно сделать IntToStr...)

подскажете?


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Ты забыла еще одну пару:
fgetc/fputc - посимвольное чтение из потока. Как раз то, что тебе нужно, если работаешь с file of byte в терминологии Паскаля... Если же тип более емкий, то я бы выбрал fread/fwrite - аналог blockread/blockwrite, нужно работать с int, тогда

int i;
FILE *f = fopen("file.dat", "rb");
...
fread(&i, sizeof(i), 1, f); // <--- вот и чтение одного int-а
...

Можно вообще выделить это в отдельные функции типа read_int/write_int, и работать именно с бинарным представлением (как и было в file of integer, кстати), а не с текстовым, как в случае fscanf/fprintf
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


просто человек
******

Группа: Пользователи
Сообщений: 3 641
Пол: Женский
Реальное имя: Юлия

Репутация: -  55  +


спасибо!


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


просто человек
******

Группа: Пользователи
Сообщений: 3 641
Пол: Женский
Реальное имя: Юлия

Репутация: -  55  +


Пишу:
void MakeFile (void)
{
FILE *f = fopen("vvod.dat", "wb+");
randomize();
int n=random(50)+50;
for (int j=1;j<n;j++)
{
int i=random(500);
fwrite(&i, sizeof(i), 1, f);
Form1->Memo1->Lines->Add(IntToStr(i));
}
fclose(f);
}
//---------------------------------------------------------------------------
void ShowFile (void)
{
FILE *f;
if ((f = fopen("vvod.dat", "rb")))
{
while (!(feof(f)))
{
int i;
fread(&i,sizeof(i), 1, f);
Form1->Memo2->Lines->Add(IntToStr(i));
}
}
else
ShowMessage("!!!");
fclose(f);
}

Все замечательно, но последний элемент выводится дважды... То есть в Memo2 оказывается на строчку больше...
Почему такое может быть?


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Гость






Цитата
Почему такое может быть?
Потому, что нужно анализировать результат, возвращаемый fread: если она ничего не прочла из файла, то вернется 0 (ты забыла про #26 - символ конца файла, формально конец файла еще не достигнут, т.е. feof() возвращает "ложь", но при попытке считывания очередного числа происходит считывание #26, и число, естественно, не читаясь заново, остается тем же, что и было прочитано в прошлый раз)...

    while (!(feof(f)))
{
int i;
if( fread(&i,sizeof(i), 1, f) != 0 )
Form1->Memo2->Lines->Add(IntToStr(i));
}
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


просто человек
******

Группа: Пользователи
Сообщений: 3 641
Пол: Женский
Реальное имя: Юлия

Репутация: -  55  +


tnx.
...и еще вопрос возник: как можно узнать размер файла? то есть нужен аналог SizeOf(F).
на lengthfile ругается, что вообще такого не знает.
GetSizeFile работает, но как-то непонятно.... Что-то совершенно не то возвращает.
Если это повлияет на ответ, конкретизирую задание.
После сортировки у меня получается 3 файла: 2 пустых и 1 с отсортированной последовательностью. Пустые надо удалять, а полный переименовывать. Просто запомнить номер в принципе возможно, но достаточно проблематично...


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Гость






Из хелпа Turbo C++ 3.0:
  long filesize(FILE *stream)
{
long curpos, length;

curpos = ftell(stream);
fseek(stream, 0L, SEEK_END);
length = ftell(stream);
fseek(stream, curpos, SEEK_SET);
return length;
}
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


просто человек
******

Группа: Пользователи
Сообщений: 3 641
Пол: Женский
Реальное имя: Юлия

Репутация: -  55  +


понимаю, что уже замучала....
но опять с вопросами:
...
fclose(Lenta[TAPE[T-1]]);
Lenta[TAPE[T-1]]=fopen(("L"+IntToStr(TAPE[T-1])+".dat").c_str(),"rb+");
...

Куда устанавливает указатель fopen? В начало файла или в конец?


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


просто человек
******

Группа: Пользователи
Сообщений: 3 641
Пол: Женский
Реальное имя: Юлия

Репутация: -  55  +


...нашла ошибку. а вот как ее избежать...
как можно указатель "отмотать" на 1 элемент назад?
пробовала
fseek(Lenta[TAPE[i]],-1*sizeof(i),SEEK_CUR); 
- че-то не то.

Сообщение отредактировано: volvo -


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Гость






Юля, а при чем здесь sizeof(int)? Надо делать sizeof(struct) ...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


просто человек
******

Группа: Пользователи
Сообщений: 3 641
Пол: Женский
Реальное имя: Юлия

Репутация: -  55  +


а что есть struct?...
у меня ситуация какая: при некотором условии получается, что я считываю лишний элемент (int). то есть надо вернуться и считать его еще раз... соответственно, возвращаюсь именно на размер int'а.
не так?


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Гость






Тогда приведи описания Lenta и TAPE ...

Цитата
при некотором условии получается, что я считываю лишний элемент (int)
Так вот при этом условии НЕ считывай ничего из файла... Как ты хочешь, чтоб тебе подсказали, если ничего не привела, ни ОТКУДА читаешь, ни КУДА, ни СКОЛЬКО...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


просто человек
******

Группа: Пользователи
Сообщений: 3 641
Пол: Женский
Реальное имя: Юлия

Репутация: -  55  +


void MergeSort(void)
{
const T=3,p=2;
int suma=0,sumd=0;
int A[T],D[T],TAPE[T];
MakeFile();
Start(T,p,A,D,TAPE,&suma,&sumd);
FILE *Lenta[3];
Lenta[TAPE[T-1]]=fopen("L2.dat","wb+");
for (int j=0;j<T-1;j++)
Lenta[TAPE[j]]=fopen(("L"+IntToStr(j)+".dat").c_str(),"rb");
int Dmax=0, Dost[3];
int sort[3];
while (Dmax<suma)
{
while ( ((fread(&sort[0],sizeof(sort[0]),1,Lenta[TAPE[0]]))!=0)&&((fread(&sort[1],sizeof(sort[1]),1,Lenta[TAPE[1]]))!=0) )
//вот здесь считывается лишнее - одна лента кончилась, а вторая еще нет
{
for (int j=0;j<T;j++)
Dost[j]=D[j];
int zerro=0;
while (zerro<T-1)
{
int min=MaxInt;
int mini;
for (int i=0;i<T-1;i++)
if ((sort[TAPE[i]]<=min)&&(Dost[TAPE[i]]>0))
{
min=sort[TAPE[i]];
mini=i;
}
fwrite(&min,sizeof(min),1,Lenta[TAPE[T-1]]);
Dost[TAPE[mini]]--;
if (Dost[TAPE[mini]]>0)
fread(&sort[TAPE[mini]],sizeof(sort[mini]),1,Lenta[TAPE[mini]]);
else
{
sort[TAPE[mini]]=MaxInt;
zerro++;
}
}
}
for (int i=0;i<T-1;i++)
if (feof(Lenta[TAPE[i]])) //если кончилась лента....
{
D[TAPE[T-1]]=0;
for (int j=0;j<T-1;j++)
D[TAPE[T-1]]+=D[TAPE[j]];
Dmax=D[TAPE[T-1]];
int zap;
fclose(Lenta[TAPE[T-1]]);
Lenta[TAPE[T-1]]=fopen(("L"+IntToStr(TAPE[T-1])+".dat").c_str(),"rb");
int j=TAPE[i];
TAPE[i]=TAPE[T-1];
TAPE[T-1]=j;
fclose(Lenta[TAPE[T-1]]);
Lenta[TAPE[T-1]]=fopen(("L"+IntToStr(TAPE[T-1])+".dat").c_str(),"wb+");
}
else
fseek(Lenta[TAPE[i]],-1*sizeof(i),SEEK_CUR); //а если не кончилась, надо вернуться к предыдущему эл-ту...
}

fcloseall;
}


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Гость






Единственное, что приходит в голову - попробуй вот так (нужно привести смещение к типу long):
fseek(Lenta[TAPE[i]], - (long)sizeof(sort[0]), SEEK_CUR);


Кстати, ты уверена, что когда эта операция должна происходить, то есть куда откатываться? Если текущая позиция будет равна 0 (самое начало файла), то будет ошибка и fseek вернет -1...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


просто человек
******

Группа: Пользователи
Сообщений: 3 641
Пол: Женский
Реальное имя: Юлия

Репутация: -  55  +


уверена...
0 возвращает.
типа промоталась.
а считывать потом все равно отказывается.


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Гость






Юля, присоединить весь проект с данными вместе (в архиве) сможешь? Так, чтобы можно было скомпилировать и пройти пошагово... Просто интересно, что можно сделать в этом случае...

Можно на PM ...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


просто человек
******

Группа: Пользователи
Сообщений: 3 641
Пол: Женский
Реальное имя: Юлия

Репутация: -  55  +


вот...
лр4.rar
дубль 1.rar - то же самое на делфи. с маленьким отличием: работает так, как надо....


Прикрепленные файлы
Прикрепленный файл  ______1.rar ( 9.5 килобайт ) Кол-во скачиваний: 177
Прикрепленный файл  __4.rar ( 390.11 килобайт ) Кол-во скачиваний: 172


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Гость






Так... Значит, я добил эту программу (в смысле, она теперь работоспособна, единственное что нужно сделать - пройтись по ней, и убрать лишний индекс во всех массивах... Я сделал везде описание int ... [T+1])... Выкладываю только что отработавшую у меня под TC3.0 (Builder-а, к сожалению, не имею...) версию вместе со всей отладочной информацией, может она поможет тебе разобрать что к чему... Работает ТОЧНО так же, как и Дельфийская...

Основная идея (в двух словах) - замени стандартную функцию feof() на вот такую:
int fEOF(FILE *stream)
{
return (ftell(stream) == filesize(stream) || feof(stream));
}
и тот самый проблемный цикл сделай не
while( (!feof(Lenta[TAPE[1]])) && (!feof(Lenta[TAPE[2]])) ) {
...
}

, а
do {
...
} while( (!fEOF(Lenta[TAPE[1]])) && (!fEOF(Lenta[TAPE[2]])) );

smile.gif

P.S. Расширение - PAS, потому что CPP файлы пока нельзя приаттачивать...


Прикрепленные файлы
Прикрепленный файл  __MISS__.PAS ( 7.35 килобайт ) Кол-во скачиваний: 262
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


просто человек
******

Группа: Пользователи
Сообщений: 3 641
Пол: Женский
Реальное имя: Юлия

Репутация: -  55  +


Супер! Спасибо огромное....
Буду разбираться....


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 29.03.2024 7:21
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name