1. Пользуйтесь тегами кода. - [code] ... [/code] 2. Точно указывайте язык, название и версию компилятора (интерпретатора). 3. Название темы должно быть информативным. В описании темы указываем язык!!!
есть алгоритм многофазной сортировки, которая работает с файлами. в делфи это был 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-а ...
Можно вообще выделить это в отдельные функции типа read_int/write_int, и работать именно с бинарным представлением (как и было в file of integer, кстати), а не с текстовым, как в случае fscanf/fprintf
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует. На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
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 оказывается на строчку больше... Почему такое может быть?
--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует. На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
Потому, что нужно анализировать результат, возвращаемый fread: если она ничего не прочла из файла, то вернется 0 (ты забыла про #26 - символ конца файла, формально конец файла еще не достигнут, т.е. feof() возвращает "ложь", но при попытке считывания очередного числа происходит считывание #26, и число, естественно, не читаясь заново, остается тем же, что и было прочитано в прошлый раз)...
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 с отсортированной последовательностью. Пустые надо удалять, а полный переименовывать. Просто запомнить номер в принципе возможно, но достаточно проблематично...
--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует. На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
Куда устанавливает указатель fopen? В начало файла или в конец?
--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует. На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
...нашла ошибку. а вот как ее избежать... как можно указатель "отмотать" на 1 элемент назад? пробовала
fseek(Lenta[TAPE[i]],-1*sizeof(i),SEEK_CUR);
- че-то не то.
Сообщение отредактировано: volvo -
--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует. На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
а что есть struct?... у меня ситуация какая: при некотором условии получается, что я считываю лишний элемент (int). то есть надо вернуться и считать его еще раз... соответственно, возвращаюсь именно на размер int'а. не так?
--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует. На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
при некотором условии получается, что я считываю лишний элемент (int)
Так вот при этом условии НЕ считывай ничего из файла... Как ты хочешь, чтоб тебе подсказали, если ничего не привела, ни ОТКУДА читаешь, ни КУДА, ни СКОЛЬКО...
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; }
--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует. На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
Кстати, ты уверена, что когда эта операция должна происходить, то есть куда откатываться? Если текущая позиция будет равна 0 (самое начало файла), то будет ошибка и fseek вернет -1...
уверена... 0 возвращает. типа промоталась. а считывать потом все равно отказывается.
--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует. На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
Юля, присоединить весь проект с данными вместе (в архиве) сможешь? Так, чтобы можно было скомпилировать и пройти пошагово... Просто интересно, что можно сделать в этом случае...
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует. На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
Так... Значит, я добил эту программу (в смысле, она теперь работоспособна, единственное что нужно сделать - пройтись по ней, и убрать лишний индекс во всех массивах... Я сделал везде описание int ... [T+1])... Выкладываю только что отработавшую у меня под TC3.0 (Builder-а, к сожалению, не имею...) версию вместе со всей отладочной информацией, может она поможет тебе разобрать что к чему... Работает ТОЧНО так же, как и Дельфийская...
Основная идея (в двух словах) - замени стандартную функцию feof() на вот такую:
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует. На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!