есть алгоритм многофазной сортировки, которая работает с файлами. в делфи это был file of integer.
поскольку в с++ абсолютного аналога нет, возник вопрос - что выбрать из имеющихся средств?
Запуталась
В чем разница между парами:
fread-fwrite; (для всего подряд?)
fscanf-fprintf; (форматированный ввод/вывод? то есть %d - и будет мне десятичное целое число, как и хочется?)
fgets-fputs; (это вроде для строк.... то есть потом можно сделать IntToStr...)
подскажете?
Ты забыла еще одну пару:
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-а
...
спасибо!
Пишу:
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);
}
while (!(feof(f)))
{
int i;
if( fread(&i,sizeof(i), 1, f) != 0 )
Form1->Memo2->Lines->Add(IntToStr(i));
}
tnx.
...и еще вопрос возник: как можно узнать размер файла? то есть нужен аналог SizeOf(F).
на lengthfile ругается, что вообще такого не знает.
GetSizeFile работает, но как-то непонятно.... Что-то совершенно не то возвращает.
Если это повлияет на ответ, конкретизирую задание.
После сортировки у меня получается 3 файла: 2 пустых и 1 с отсортированной последовательностью. Пустые надо удалять, а полный переименовывать. Просто запомнить номер в принципе возможно, но достаточно проблематично...
Из хелпа 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;
}
понимаю, что уже замучала....
но опять с вопросами:
...
fclose(Lenta[TAPE[T-1]]);
Lenta[TAPE[T-1]]=fopen(("L"+IntToStr(TAPE[T-1])+".dat").c_str(),"rb+");
...
...нашла ошибку. а вот как ее избежать...
как можно указатель "отмотать" на 1 элемент назад?
пробовала
fseek(Lenta[TAPE[i]],-1*sizeof(i),SEEK_CUR);- че-то не то.
Юля, а при чем здесь sizeof(int)? Надо делать sizeof(struct) ...
а что есть struct?...
у меня ситуация какая: при некотором условии получается, что я считываю лишний элемент (int). то есть надо вернуться и считать его еще раз... соответственно, возвращаюсь именно на размер int'а.
не так?
Тогда приведи описания Lenta и TAPE ...
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;
}
Единственное, что приходит в голову - попробуй вот так (нужно привести смещение к типу long):
fseek(Lenta[TAPE[i]], - (long)sizeof(sort[0]), SEEK_CUR);
уверена...
0 возвращает.
типа промоталась.
а считывать потом все равно отказывается.
Юля, присоединить весь проект с данными вместе (в архиве) сможешь? Так, чтобы можно было скомпилировать и пройти пошагово... Просто интересно, что можно сделать в этом случае...
Можно на PM ...
вот...
лр4.rar
дубль 1.rar - то же самое на делфи. с маленьким отличием: работает так, как надо....
Прикрепленные файлы
______1.rar ( 9.5 килобайт )
Кол-во скачиваний: 180
__4.rar ( 390.11 килобайт )
Кол-во скачиваний: 175
Так... Значит, я добил эту программу (в смысле, она теперь работоспособна, единственное что нужно сделать - пройтись по ней, и убрать лишний индекс во всех массивах... Я сделал везде описание 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]])) );
Супер! Спасибо огромное....
Буду разбираться....