Новые книги

Книга содержит практические способы привлечения новых клиентов для бизнеса из социальных сетей. Более подробно в ней разобраны основные принципы продвижения бизнес-страниц в таких социальных сообществах, как «ВКонтакте» и «Facebook». Во второй части книги детально рассмотрены отдельные примеры продвижения. Ключевые моменты издания:

– этапы и последовательность действий по привлечению клиентов;

– получение потока клиентов;

– монетизация;

– оптимизация сайта;

– оформление бизнес-страниц;

– генерация и публикация контента.

Рекомендуется всем, кто хочет использовать новые источники привлечения клиентов.
Не так давно от столь популярного в наше время прилагательного «креативный»1 образовалось новое существительное. Если вы — один из нас, миллионов людей, зарабатывающих на жизнь своим умом, вас можно смело назвать представителем «креативного класса», или попросту — креативщиком. Каждый день вы решаете проблемы, предлагаете нововведения, разрабатываете системы, создаете дизайнерские решения, пишете, занимаетесь стратегическим планированием и работаете головой. Именно благодаря вам рождаются новые концепции и формируются целые рабочие системы, закладывающие основу будущего экономического роста, — создается принципиально новый продукт, которого не было и в помине, пока на сцену не вышли вы.

Может быть, вы вовсе и не собирались становиться творческой личностью. Более того, возможно, вы даже содрогаетесь всякий раз, когда вас называют «креативным». И это вполне понятно, ведь ярлык «креативщик» обычно вызывает в воображении этакого рекламного гуру из Сохо2, мельтешащего туда-сюда в своих фирменных джинсах за 500 долларов. Скорее всего, вам приятнее называть себя стратегом или менеджером, что звучит более определенно, более реально. Называйте себя как пожелаете, но если вы отвечаете за решение проблем, разработку стратегий или напряженно трудитесь над генерированием новых идей, я буду называть вас креативщиком, даже если выходит, что вы стали им случайно.

Примеры.

Пример 18

/* _______________________ файл glob.h ___________________________*/
/* ПОДДЕРЖКА СПИСКА ИМЕН ФАЙЛОВ ЗАДАННОГО КАТАЛОГА                */
/* ______________________________________________________________ */
#define FILF
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
# define DIR_SIZE 14
extern char *malloc(unsigned); char *strdup(const char *str);
extern char *getenv();
extern char *strchr(char *, char),  *strrchr(char *, char);
#define ISDIR(mode) ((mode & S_IFMT) == S_IFDIR)
#define ISDEV(mode) ((mode & S_IFMT) & (S_IFCHR|S_IFBLK))
#define ISREG(mode) ((mode & S_IFMT) == S_IFREG)
#define ISEXE(mode) ((mode & S_IFMT) == S_IFREG && (mode & 0111))
#define isdir(st)   ISDIR(st.st_mode)
#define isdev(st)   ISDEV(st.st_mode)
#define isreg(st)   ISREG(st.st_mode)
#define isexe(st)   ISEXE(st.st_mode)
#define YES      1
#define NO       0
#define I_DIR    0x01     /* это имя каталога      */
#define I_EXE    0x02     /* это выполняемый файл  */
#define I_NOSEL  0x04     /* строку нельзя выбрать */
#define I_SYS    (I_DIR | I_EXE | I_NOSEL)
/* Скопировано из treemk.c
 * Лучше просто написать #include "glob.h" в файле treemk.c
 */
#define FAILURE (-1)            /* код неудачи */
#define SUCCESS   1             /* код успеха  */
#define WARNING   0             /* нефатальная ошибка */
typedef struct _info {    /* структура элемента каталога */
	char *s;          /* имя файла                   */
	short fl;         /* флаг                        */
	union _any{
	   int (*act)();     /* возможно связанное действие */
	   char *note;       /* или комментарий             */
	   unsigned i;       /* или еще какой-то параметр   */
	   struct _info *inf;
	} any;            /* вспомогательное поле        */
#ifdef FILF
/* дополнительные необязательные параметры, получаемые из stat(); */
	long size;
	int uid, gid;
	unsigned short mode;
#endif
} Info;
typedef union _any Any;
extern Info NullInfo;
#define MAX_ARGV 256      /* Максимальное число имен в каталоге */
typedef struct {          /* Содержимое каталога name */
	time_t lastRead;  /* время последнего чтения каталога  */
	Info *files;      /* содержимое каталога               */
	char *name;       /* имя каталога                      */
	ino_t ino; dev_t dev; /* I-узел и устройство           */
	char valid;       /* существует ли этот каталог вообще */
	short readErrors; /* != 0, если каталог не читается    */
} DirContents;
     /* Виды сортировки имен в каталоге */
typedef enum { SORT_ASC, SORT_DESC, SORT_SUFX,
	       SORT_NOSORT, SORT_SIZE }         Sort;
extern Sort sorttype; extern int in_the_root;
int   gcmps (const void *p1, const void *p2);
Info *blkcpy(Info *v); void blkfree(Info *v);
Info *glob(char **patvec,  char *dirname);
Info *glb(char   *pattern, char *dirname);
int ReadDir(char *dirname, DirContents *d);
struct savech{ char *s, c; };
#define SAVE(sv, str) (sv).s = (str); (sv).c = *(str)
#define RESTORE(sv) if((sv).s)   *(sv).s = (sv).c
/* _______________________ файл glob.c __________________________ */
#include "glob.h"
int in_the_root = NO;        /* читаем корневой каталог ?     */
Sort sorttype = SORT_SUFX;   /* сортировка имен по суффиксу   */
Info NullInfo = { NULL, 0 }; /* и прочие поля = 0 (если есть) */
char *strdup(const char *s){
   char *p = malloc(strlen(s)+1); if(p)strcpy(p, s); return p; }
/* Содержится ли любой из символов в строке ? */
int any(register char *s, register char *p){
   while( *s ){ if( strchr(p, *s)) return YES; s++; }
   return NO;
}
/* Найти последнюю точку в имени */
static char *lastpoint (char *s)
{   register char *last; static char no[] = "";
    if((last = strchr(s, '.')) == NULL) return no;
    /* если имя начинается с точки - не считать ее */
    return( last == s ? no : last );
}
/* Сравнение строк с учетом их суффиксов */
int strsfxcmp (register char *s1, register char *s2){
    char *p1, *p2, c1, c2; int code;
    p1 = lastpoint (s1); p2 = lastpoint (s2);
    if (code = strcmp (p1, p2)) return code; /* суффиксы разные */
    /* иначе: суффиксы равны. Сортируем по головам              */
    c1 = *p1; c2 = *p2; *p1 = '\0'; *p2 = '\0'; /* временно     */
    code = strcmp (s1, s2);
    *p1 = c1; *p2 = c2; return code;
}
/* Функция сортировки */
int gcmps(const void *p1, const void *p2){
    Info *s1 = (Info *) p1, *s2 = (Info *) p2;
    switch( sorttype ){
    default:
    case SORT_ASC:    return    strcmp(s1->s, s2->s);
    case SORT_DESC:   return   -strcmp(s1->s, s2->s);
    case SORT_SUFX:   return strsfxcmp(s1->s, s2->s);
    case SORT_NOSORT: return (-1);
#ifdef FILF
    case SORT_SIZE:   return (s1->size <  s2->size ? -1 :
			      s1->size == s2->size ? 0 : 1 );
#endif
    }
}
/* Копирование блока */
Info *blkcpy(Info *v){
    register i, len;
    Info *vect = (Info *) malloc(((len=blklen(v)) + 1) * sizeof(Info));
    for(i=0; i < len; i++ ) vect[i] = v[i];
    vect[len] = NullInfo;   return vect;
}
/* Измерение длины блока */
int blklen(Info *v){
    int i = 0;
    while( v->s ) i++, v++;
    return i;
}
/* Очистка блока (уничтожение) */
void blkfree(Info *v){
     Info *all = v;
     while( v->s )
	    free((char *) v->s ), v++;
     free((char *) all );
}
/* Сравнение двух блоков */
int blkcmp( register Info *p, register Info *q ){
    while( p->s && q->s && !strcmp(p->s, q->s) &&
	  (p->fl & I_SYS) == (q->fl & I_SYS)){ p++; q++; }
    if( p->s == NULL && q->s == NULL )
	return 0;       /* совпадают   */
    return 1;           /* различаются */
}
char   globchars [] = "*?[";
Info gargv[MAX_ARGV]; int gargc;
static short readErrors;
void greset() { gargc = 0; readErrors = 0; }
/* Расширить шаблон имен файлов в сами имена */
static void globone(char *pattern, char dirname[]){
     extern char *strdup(); struct stat st;
     DIR *dirf; struct dirent *d;
     if( any(pattern, globchars) == NO ){  /* no glob */
	     gargv[gargc]   = NullInfo;
	     gargv[gargc].s = strdup(pattern);
	     gargc++;
	     gargv[gargc]   = NullInfo;
	     return;
     }
     if((dirf = opendir(dirname)) == NULL){ readErrors++; goto out; }
     while(d = readdir(dirf)){
       if(match(d->d_name, pattern)){
	  char fullname[512];
	  if( sorttype != SORT_NOSORT && !strcmp(d->d_name, "."))
	      continue;
	  /* В корневом каталоге имя ".." следует пропускать */
	  if( in_the_root && !strcmp(d->d_name, "..")) continue;
	  /* Проверка на переполнение */
	  if( gargc == MAX_ARGV - 1){
	      free(gargv[gargc-1].s);
	      gargv[gargc-1].s  = strdup(" Слишком много файлов!!!");
	      gargv[gargc-1].fl = I_SYS;
	      break;
	  }
	  gargv[gargc]     = NullInfo;
	  gargv[gargc].s   = strdup(d->d_name);
	  sprintf(fullname, "%s/%s", dirname, d->d_name);
	  if(stat(fullname, &st) < 0) gargv[gargc].fl |= I_NOSEL;
	  else if(isdir(st))          gargv[gargc].fl |= I_DIR;
	  else if(isexe(st))          gargv[gargc].fl |= I_EXE;
#ifdef FILF
	  gargv[gargc].size = st.st_size;
	  gargv[gargc].uid  = st.st_uid;
	  gargv[gargc].gid  = st.st_gid;
	  gargv[gargc].mode = st.st_mode;
#endif
	  gargc++;
       }
     }
     closedir(dirf);
out: gargv[ gargc ] = NullInfo;
}
/* Расширить несколько шаблонов */
Info *glob(char **patvec, char *dirname){
      greset();
      while(*patvec){ globone(*patvec, dirname); patvec++; }
      qsort(gargv, gargc, sizeof(Info), gcmps);
      return blkcpy(gargv);
}
Info *glb(char *pattern, char *dirname){ char *pv[2];
      pv[0] = pattern; pv[1] = NULL; return glob(pv, dirname);
}
/* Прочесть содержимое каталога, если оно изменилось:
 * Вернуть: 0  - каталог не менялся;
 *          1  - изменился;
 *       1000  - изменился рабочий каталог (chdir);
 *          -1 - каталог не существует;
 */
int ReadDir(char *dirname, DirContents *d){
    struct stat st; Info *newFiles;
    int save = YES; /* сохранять метки у файлов ? */
    int dirchanged = NO; /* сделан chdir() ? */
    /* каталог мог быть удален, а мы об этом не извещены */
    if( stat(dirname, &st) < 0 ){
	d->valid = NO; d->lastRead = 0L;
	if(d->files) blkfree(d->files);
	d->files = blkcpy( &NullInfo );
	return (-1); /* не существует */
    } else d->valid = YES;
    /* не изменился ли адрес каталога, хранимого в *d ? */
    if(d->ino != st.st_ino || d->dev != st.st_dev){ /* изменился */
       d->ino  = st.st_ino;   d->dev  = st.st_dev;
       save = NO; d->lastRead = 0L; dirchanged = YES;
    }
    /* не изменилось ли имя каталога ? */
    if( !d->name || strcmp(d->name, dirname)){
	if(d->name) free(d->name); d->name = strdup(dirname);
	/* save=NO; d->lastRead = 0; */
    }
    /* проверим, был ли модифицирован каталог ? */
    if( save==YES && d->files && st.st_mtime == d->lastRead )
	return 0;       /* содержимое каталога не менялось */
    d->lastRead = st.st_mtime;
    newFiles = glb("*", d->name);  /* прочесть содержимое каталога */
    if(save == YES && d->files){
	register Info *p, *q;
	if( !blkcmp(newFiles, d->files)){
	     blkfree(newFiles); return 0;  /* не изменилось */
	} /* иначе сохранить пометки */
	for(p= d->files; p->s; p++)
	  for(q= newFiles; q->s; ++q)
	    if( !strcmp(p->s, q->s)){
		q->fl |= p->fl & ~I_SYS;   break;
	    }
    }
    if(d->files) blkfree(d->files);
    d->files = newFiles; d->readErrors = readErrors;
    return 1 + (dirchanged ? 999:0);
    /* каталог изменился */
}

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

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