osn_progr_final
.pdfelse
if( (fp = fopen( name, "r" )) == NULL ){ fprintf( stderr, "Не можу відкрти файл %s\n",
name ); return;
} |
|
|
|
printf( "---------------------------- |
%s---- |
\n", |
|
name ); |
|
|
|
while( fgets( l, MAXL, fp ) != NULL ){ |
|
|
|
len = strlen( l ); |
|
|
|
if( len && l[len-1] == '\n' ) |
|
|
|
l[-- |
len] = '\0' ; |
|
|
if( nwords = parse( l, words)){ |
|
|
|
/* друк слів в зворотному порядку */ |
|
||
for( --nwords; nwords >= 0; nwords-- |
){ |
||
|
printf( "%s ", words[ nwords] ); |
||
|
add( words[ nwords ] ); |
|
|
} |
|
|
|
}
putchar ('\n');
}
if( fp != stdin ) fclose( fp );
}
/* розкласти рядок на слова */ parse( s, tabl )
register unsigned char *s; unsigned char *tabl[];
{
char eol = 0; int nwords = 0;
while ( !eol ){
/* пропустити пропуски та табуляції */ while(isspace(*s)) s++;
if( !*s ) /* рядок закінчився */ break;
*tabl++ = s; nwords++;
/* початок чергового слова */ /* пока не пропуск і не кінець рядка */ while( *s && !isspace(*s))s++;
/* вказівник вказує на символ що є наступним за словом */
if( ! *s ) eol ++;
201
*s = '\0';
/* закрили Слово, починаємо Діло */ s++;
}
*tabl = NULL; return nwords;
}
/* побудова таблиці слів, що зустрічаються в файлі */
#define MAXWORDS 1024
struct W{ |
|
int ctr; |
/* число входжень слова */ |
char *wrd; |
/* слово */ |
}w [MAXWORDS]; |
/* таблиця */ |
int busy = 0 ; |
/* занято в таблиці */ |
extern char *malloc();
/* Добавити слово в таблицю */ add( word ) char *word;
{
register i; static alert = 1;
/* немає вже слова в таблиці ? */ /* якщо є - просто збільшити лічильник */ for( i = 0; i < busy ; i++ ){
if( !strcmp( word, w[i].wrd )){ w[i].ctr++;
return;
}
}
if( busy >= MAXWORDS ){ if( alert ){
fprintf( stderr, "Переповнення таблиці
слів\7\n");
alert = 0;
}
return;
}
/* ні, слова немає. Заносимо: */ w[busy].wrd = malloc( strlen( word ) + 1 );
/* 1 байт під символ \0 */
202
if( w[busy].wrd == NULL ){
fprintf( stderr, "Мало пам”яті\n");
busy = MAXWORDS+1; /* ніби переповнення */ return;
}
w[busy].ctr = 1;
strcpy( w[busy].wrd, word ); busy++;
}
compare( a, b ) struct W *a, *b;
{
return strcoll( a-> wrd, b-> wrd );
/* strcoll порівнює слова в алфавітному порядку */
}
/* друк всіх слів, що зустрічаються в тексті та кількості їх входжень */
total(){ register i;
/* сортуємо слова по алфавіту */
qsort( w, busy, sizeof(struct W), compare ); printf( "-----|-----------ИТОГ---------------\n"); for( i=0; i < busy; i++ )
printf( "%4d | %s\n", w[i].ctr, w[i].wrd
);
}
Приклад 10
Розділити дійсне число "x" на дійсне число "у" з точністю до "n" цифр після коми (40<=n<=60)
При написанні програми використаємо бібліотечну функцію fmod(x,y), яка повертає залишок від ділення числа x на y для дійсних x та y. Спочатку надрукуємо цілу частину x/y. Тоді fmod(x,y) будемо домножати на 10 доти, доки не отримаємо число більше за 1. Тоді друкуємо цілу частину цього числа. Процес продовжуємо до заданої точності n.
#include <stdio.h> #include <conio.h>
203
#include <stdlib.h> #include <math.h>
void main()
{
float x,y,z,t,s; int i,j,flag,n,k; m1:
clrscr();
printf("\n Ділене : "); scanf("%f",&x);
printf("\n Дільник : "); scanf("%f",&y);
printf("\n Введіть точність 40<=n<=60 : "); scanf("%d",&n);
printf("\n Отримали число :\n"); printf("%d.",(int)((x/y)));
for(i=0; i<n; i++)
{
flag=0;
t=fmod(x,y); if(t==0) flag=1; else flag=0;
while(!flag)
{
if(t<y) t*=10.0; else flag=1;
}
s=t/y;
if(fabs(s)>=1e-5) printf("%d",(int)s); if (s==0) printf("%d",(int)s);
x=t;
}
printf("\n Продовжуємо-7:"); scanf("%d",&k);
if(k==7){gotoxy(1,wherey()-1);delline(); goto m1; }
getch();
}
204
Приклад 11 Написати програму для організації роботи з базою даних. Вважати,
що дані являють собою сукупність деякого ключа та значення(символьного рядка).
#include <stdio.h>
/* Усі записи в базі мають фіксований розмір */
#define VLEN 20
#define KEY_FREE (-13) /*ключ вільного місця. Він довільний, але не повинен зустрічатися в якості вхідних даних
*/
struct data{ |
|
short b_key; |
/* ключ */ |
char b_val[VLEN]; |
/* рядок-значення */ |
}; |
|
char BASEF[] = ".base" ; |
/* им”я файла базы */ |
FILE *fbase; |
/* pointer на базу */ |
struct data tmp; |
/* допоміжна змінна */ |
void
initBase (void){
if(( fbase = fopen( BASEF, "r+" )) == NULL ){ if(( fbase = fopen( BASEF, "w+" )) == NULL ){
fprintf( stderr, "Не можувідкрити базу даних %s\n",BASEF );
exit(1);
}
fprintf( stderr, "База створена\n" );
}
}
void
closeBase (void){ fclose( fbase );
}
/*Врахуйте, що якщо ви записуєте у файл структури, то у файлі не буде поділу на рядки - файл НЕТЕКСТОВИЙ! Тому і читати такий файл можна тільки структурами: read(), fread() (але не scanf-ом і не fgets-ом)
*/
205
/* Пошук за ключем .
Видати (-1), якщо записа з даним ключем немає, інакше - номер слота, де міститься запис з даним
ключем.
*/ int
bget (int key)
{
int n;
/* послідовно передивитись весь файл */ rewind( fbase );
/* на початок файла. Еквівалент fseek(fbase, 0L, 0); */
n = 0 ;
/* int скільки_элементів_масиву_дійсно_зчитано =
*fread( адреса_масиву_куда_зчитувати,
*розмір_одного_элемента_масиву,
*скільки_элементів_зчитувати_в_масив, ка-
нал );
* Відмітимо,що кількість даних задається НЕ в бай-
тах,
* а в 'штуках'
*/
while( fread( &tmp, sizeof( tmp ), 1, fbase ) == 1
){
if( tmp.b_key == key ) return n;
n++;
}
return (-1); /* не знайдено */
}
/* модифікувати запис з індексом ind */
void |
|
bmod ( |
|
int ind, |
|
int key, |
/* новый ключ */ |
char *val |
/* нове значення */ |
)
{
struct data new;
206
fseek( fbase, (long) sizeof( struct data ) * ind, 0
);
new.b_key = key;
strncpy( new.b_val, val, VLEN );
/* int скільки_елементів_масиву_дійсно_записано
=
* fwrite( адреса_масиву_котрий_записувати, * розмір_одного_элемента_массиву,
* скільки_елементів_масиву_записувати, ка-
нал );
*/
if( fwrite( &new, sizeof new , 1, fbase ) != 1 ) fprintf( stderr, "Помилка запису.\n" );
}
/* видалення запису по ключу */ int
bdel (int key){
int ind = bget( key ); if( ind == -1 )
return (-1); /* запису з таким ключем
немає */
bmod( ind, KEY_FREE, "" ); /* записити ознаку ві-
льного місця */ return 0;
}
/* Службова процедура дописування до кінця файла */ void
bappend (int key, char *val)
{
struct data new;
/* стати на кінець файлу */ fseek( fbase, 0L, 2 );
/* і записати нову структуру в кінець */ new.b_key = key;
strncpy( new.b_val, val, VLEN );
fwrite( &new, sizeof( struct data ) , 1, fbase
);
}
/* дописування нового запису. Якщо запис з таким ключем Вже є -видати помилку
207
*/ int
bput (int key, char *val)
{
int i = bget( key ); if( i != -1 )
return (-1); /* запис вже є */
/* знайти вільне місце */ i = bget( KEY_FREE );
if( i == -1 ) { /* немає вільних місць */ bappend( key, val );
return 0;
}
/* інакше вільне місце знайдене.
* Замінюємо дірку на корисну інформацію */ bmod( i, key, val );
}
/* роздрукувати всю базу даних підряд */ void
bprint (void){ int n;
int here = 0;
rewind( fbase ); |
|
|
n = 0; |
|
|
printf( "-номер--ключ------- |
значення------------ |
\n" |
);
while( fread( &tmp, sizeof tmp, 1, fbase ) == 1 ){ if( tmp.b_key == KEY_FREE ){
n++;
continue;
}
printf( "#%-2d| %6d\t| %s\n", n, tmp.b_key, tmp.b_val );
here ++; n++;
}
printf( "-----------------------------------------
\n" );
printf( "Довжина бази:%d Занято:%d\n\n", n, here );
}
/* заміна поля val для запису з ключем key */ int
208
bchange (int key, char *val)
{
int ind;
ind = bget( key ); if( ind == -1 ){
/* запис з таким ключом не існує */ /* Добавити як новий запис */ bput( key, val );
return 0;
}
bmod( ind, key, val ); return 1;
}
/* Аналогічна функция, яка використовує інший спосіб.
* Крім того, якщо такий ключ існує, нічого не робиться
*/ int
bchg (int key, char *val)
{
struct data d;
rewind( fbase |
); |
/* на початок файла |
*/ |
while( fread( |
&d, sizeof d, 1, fbase ) == 1 |
){ |
/* поиск ключа */ if( d.b_key == key ){
/* вернутись назад від біжучої позиції */ fseek( fbase, - (long) sizeof d, 1 );
/* не підходить (long)-sizeof d !!! */
d.b_key = key;
strncpy( d.b_val, val, VLEN ); fwrite( &d, sizeof d, 1, fbase );
/* між fread і fwrite повинен бути
* хоча б один fseek. */
fseek( fbase, 0L, 1); /* нікуди не зсу-
ватись */
return 0; |
/* зроблено */ |
}
}
return (-1); /* такого ключа не було */
}
209
/* Приклад */ void
main (void){ int i;
initBase();
bprint(); bdel( 8 );
printf( "Створюємо базу даних\n" ); bput( 1, "рядок 1" );
bput( 2, "рядок 2" ); bput( 3, "рядок 3" ); bput( 4, "рядок 4" ); bprint();
printf( "Видаляємо записи з ключами 1 і 3\n" ); bdel( 1 );
bdel( 3 ); bprint();
printf( "Добавляємо записи 5, 6 і 7\n" ); bput( 5, "рядок 5" );
bput( 6, "рядок 6" ); bput( 7, "рядок 7" ); bprint();
printf( "Замінюємо рядок в запису з ключем 2\n" ); bchange( 2, "новий рядок 2" );
bprint();
printf( "Замінюємо рядок в запису з ключем 4\n" ); bchange( 4, "новий рядок 4" );
bprint();
printf( "Замінюємо рядок в запису з ключем 3 і ключ 3 на
9\n" );
bchange( 2, "новий рядок 2" ); bprint();
i = bget( 3 );
printf( "Зараз запис з ключем 3 містить
\"%s\"\n",tmp.b_val);
bmod( i, 8, "Новий рядок 3/9" ); bprint();
210