Новые книги

В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стан­дартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым.

Для начинающих Linux-программистов
Наша эра неограниченного доступа к информации – лучшее время, чтобы начать свое дело. Тем более, что маркетинг теперь стал… бесплатным.

Каждый день в мире появляются прибыльные проекты, которые не требуют крупных вложений в рекламу. И каждый день рождаются интереснейшие идеи эффективного маркетинга. Чтобы запустить проект мечты, не обязательно читать эту книгу от корки до корки, можете позаимствовать самые сливки. Вам подойдут не все идеи, но скорее всего, подойдет большинство. Все они крайне экономичны, если не бесплатны, – и, главное, эффективны. Большинство стратегий касаются использования интернета как мощного средства маркетинга, однако есть и те, что не связаны с интернетом.

Примеры.

Пример 8

/* Пример маленькой базы данных.
 * Данные хранятся БЕЗ дубликатов.
 * Надо заметить, что используется плохой (неэффективный)
 * алгоритм доступа - линейный поиск.
 */
#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){
	/* fopen: r  read  (чтение)
	 *        w  write (запись), файл пересоздается.
	 * (создается, если не было, если был - опустошается).
	 *        r+ чтение и запись (файл уже существует).
	 *        w+ чтение и запись (создается пустой файл).
	 *        a  append (запись в конец файла), создать если нет:
	 *           имеется в виду, что КАЖДАЯ операция записи сначала
	 *           ставит указатель записи на конец файла.
	 * В MS DOS нетекстовый файл НЕОБХОДИМО открывать как
	 *        rb wb rb+ wb+ ab+  иначе ничего не будет работать.
	 */
	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-ом)
 */
 
/* Поиск по ключу .
   Выдать (-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;
	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 );
}
/* добавление новой записи. Если запись с таким ключом уже есть    выдать ошибку
 */
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
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);    /* такого ключа не было */
}
/* Пример */
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" );
	bchg( 4, "новая строка 4" );
	bprint();
	printf( "Заменяем строку в записи с ключом 6 и ключ 6 на 8\n" );
	i = bget( 6 );
	printf( "Сейчас запись с ключом 6 содержит \"%s\"\n",
		tmp.b_val );
	bmod( i, 8, "Новая строка 6/8" );
	bprint();
	closeBase();
}

© Copyright А. Богатырев, 1992-95
Си в UNIX

Назад | Содержание | Вперед