Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)
Demon's Souls |#9| Heart of surprises

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Богатырев А. Весь текст 1009.15 Kb

Хрестоматия по программированию на Си в Unix

Предыдущая страница Следующая страница
1 ... 14 15 16 17 18 19 20  21 22 23 24 25 26 27 ... 87
обращение по записи в эту страницу вызывает прерывание от диспетчера памяти и аварий-
ное  прекращение процесса.  Система сама помогает ловить ваши ошибки (но уже во время
выполнения программы). Это ОЧЕНЬ частая ошибка - запись по  адресу  NULL.  MS  DOS  в
таких  случаях предпочитает просто зависнуть, и вы бываете вынуждены играть аккорд из
трех клавиш - Ctrl/Alt/Del, так и не поняв в чем дело.

2.60.  Раз уж речь зашла о функции strdup (кстати, это стандартная функция), приведем
еще одну функцию для сохранения строк.

    char *savefromto(register char *from, char *upto)
    {
            char *ptr, *s;

            if((ptr = (char *) malloc(upto - from + 1)) == NULL)
                    return NULL;

            for(s = ptr; from < upto; from++)
                    *s++ = *from;

            *s = '\0';
            return ptr;
    }

Сам символ (*upto) не сохраняется, а заменяется на '\0'.

2.61.  Упрощенный аналог функции printf.

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

    /*
     * Машинно - независимый printf() (упрощенный вариант).
     * printf - Форматный Вывод.
     */
    #include 
    #include 
    #include 
    #include 
    #include 

    extern int errno;       /* код системной ошибки, формат %m */

    /* чтение значения числа */
    #define GETN(n,fmt)                      \
            n = 0;                           \
            while(isdigit(*fmt)){            \
                    n = n*10 + (*fmt - '0'); \
                    fmt++;                   \
            }

    void myprintf(fmt, va_alist)
           register char *fmt; va_dcl
    {
      va_list ap;
      char c, *s; int i;
      int width, /* минимальная ширина поля */
          prec,  /* макс. длина данного */
          sign,  /* выравнивание: 1 - вправо, -1 - влево */
          zero,  /* ширина поля начинается с 0 */
          glong; /* требуется длинное целое */

      va_start(ap);
      for(;;){
         while((c = *fmt++) != '%'){
           if( c == '\0' ) goto out;
           putchar(c);
         }
         sign = 1; zero = 0; glong = 0;
         if(*fmt == '-'){ sign = (-1); fmt++; }
         if(*fmt == '0'){ zero = 1; fmt++; }
         if(*fmt == '*'){
             width = va_arg(ap, int);
             if(width < 0){ width = -width; sign = -sign; }
             fmt++;
         }else{
             GETN(width, fmt);
         }
         width *= sign;

         if(*fmt == '.'){
            if(*++fmt == '*'){
               prec = va_arg(ap, int); fmt++;
            }else{
               GETN(prec, fmt);
            }
         }else prec = (-1); /* произвольно */

         if( *fmt == 'l' ){
            glong = 1; fmt++;
         }

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

         switch(c = *fmt++){
         case 'c':
            putchar(va_arg(ap, int)); break;
         case 's':
            prStr(width, prec, va_arg(ap, char *)); break;
         case 'm':
            prStr(width, prec, strerror(errno));    break;
            /* strerror преобразует код ошибки в строку-расшифровку */
         case 'u':
            prUnsigned(width,
                      glong ? va_arg(ap, unsigned long) :
                              (unsigned long) va_arg(ap, unsigned int),
                      10 /* base */, zero); break;
         case 'd':
            prInteger(width,
                      glong ? va_arg(ap, long) : (long) va_arg(ap, int),
                      10 /* base */, zero);  break;
         case 'o':
            prUnsigned(width,
                      glong ? va_arg(ap, unsigned long) :
                              (unsigned long) va_arg(ap, unsigned int),
                      8 /* base */, zero);   break;
         case 'x':
            prUnsigned(width,
                      glong ? va_arg(ap, unsigned long) :
                              (unsigned long) va_arg(ap, unsigned int),
                      16 /* base */, zero);  break;
         case 'X':
            prUnsigned(width,
                      glong ? va_arg(ap, unsigned long) :
                              (unsigned long) va_arg(ap, unsigned int),
                      -16 /* base */, zero); break;
         case 'b':
            prUnsigned(width,
                      glong ? va_arg(ap, unsigned long) :
                              (unsigned long) va_arg(ap, unsigned int),
                      2 /* base */, zero);   break;
         case 'a':  /* address */
            prUnsigned(width,
                      (long) (char *) va_arg(ap, char *),
                      16 /* base */, zero);  break;
         case 'A':  /* address */
            prUnsigned(width,
                      (long) (char *) va_arg(ap, char *),
                      -16 /* base */, zero); break;
         case 'r':
            prRoman(width, prec, va_arg(ap, int)); break;
         case '%':
            putchar('%'); break;
         default:
            putchar(c);   break;
         }
      }
    out:
      va_end(ap);
    }

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

    /* --------------------------------------------------------- */
    int strnlen(s, maxlen) char *s;
    {
            register n;
            for( n=0; *s && n < maxlen; n++, s++ );
            return n;
    }

    /* Печать строки */
    static prStr(width, prec, s) char *s;
    {
      int ln;         /* сколько символов выводить */
      int toLeft = 0; /* к какому краю прижимать   */

      if(s == NULL){ pr( "(NULL)", 6); return; }

      /* Измерить длину и обрубить длинную строку.
       * Дело в том, что строка может не иметь \0 на конце, тогда
       * strlen(s) может привести к обращению в запрещенные адреса */
      ln = (prec > 0 ? strnlen(s, prec) : strlen(s));

      /* ширина поля */
      if( ! width ) width = (prec > 0 ? prec : ln);
      if( width < 0){ width = -width; toLeft = 1; }
      if( width > ln){
            /* дополнить поле пробелами */
            if(toLeft){ pr(s, ln); prSpace(width - ln, ' ');  }
            else      { prSpace(width - ln, ' '); pr(s, ln);  }
      }     else      { pr(s, ln);                            }
    }

    /* Печать строки длиной l */
    static pr(s, ln) register char *s; register ln;
    {
      for( ; ln > 0 ; ln-- )
        putchar( *s++ );
    }

    /* Печать n символов c */
    static prSpace(n, c) register n; char c;{
      for( ; n > 0 ; n-- )
        putchar( c );
    }

    /* --------------------------------------------------------- */
    static char *ds;

    /* Римские цифры */
    static prRoman(w,p,n){
            char bd[60];
            ds = bd;
            if( n < 0 ){ n = -n; *ds++ = '-'; }
            prRdig(n,6);
            *ds = '\0';
            prStr(w, p, bd);
    }

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

    static prRdig(n, d){
            if( !n ) return;
            if( d ) prRdig( n/10, d - 2);
            tack(n%10, d);
    }

    static tack(n, d){
            static char im[] = "  MDCLXVI";
                    /* ..1000 500 100 50 10 5 1 */
            if( !n ) return;
            if( 1 <= n && n <= 3 ){
                    repeat(n, im[d+2]); return;
            }
            if( n == 4 )
                    *ds++ = im[d+2];
            if( n == 4 || n == 5 ){
                    *ds++ = im[d+1]; return;
            }
            if( 6 <= n && n <= 8 ){
                    *ds++ = im[d+1];
                    repeat(n - 5, im[d+2] );
                    return;
            }
            /* n == 9 */
            *ds++ = im[d+2]; *ds++ = im[d];
    }

    static repeat(n, c) char c;
    {       while( n-- > 0 ) *ds++ = c;      }

    /* --------------------------------------------------------- */
    static char aChar = 'A';

    static prInteger(w, n, base, zero) long n;
    {
            /* преобразуем число в строку */
            char bd[128];
            int neg = 0;    /* < 0 */

            if( n < 0 ){ neg = 1; n = -n; }

            if( base < 0 ){ base = -base; aChar = 'A'; }
            else          {               aChar = 'a'; }

            ds = bd; prUDig( n, base ); *ds = '\0';
            /* Теперь печатаем строку */
            prIntStr( bd, w, zero, neg );
    }

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

    static prUnsigned(w, n, base, zero) unsigned long n;
    {
            char bd[128];

            if( base < 0 ){ base = -base; aChar = 'A'; }
            else          {               aChar = 'a'; }

            ds = bd; prUDig( n, base ); *ds = '\0';
            /* Теперь печатаем строку */
            prIntStr( bd, w, zero, 0 );
    }

    static prUDig( n, base ) unsigned long n;
    {
            unsigned long aSign;

            if((aSign = n/base ) > 0 )
                    prUDig( aSign, base );
            aSign = n % base;
            *ds++ = (aSign < 10 ? '0' + aSign : aChar + (aSign - 10));
    }

    static prIntStr( s, width, zero, neg ) char *s;
    {
      int ln;         /* сколько символов выводить */
      int toLeft = 0; /* к какому краю прижимать   */

      ln = strlen(s);            /* длина строки s */

      /* Ширина поля: вычислить, если не указано явно */
      if( ! width ){
            width = ln;  /* ширина поля    */
            if( neg )   width++;         /* 1 символ для минуса */
      }
      if( width < 0 ){ width = -width; toLeft = 1; }

      if( ! neg ){  /* Положительное число */
        if(width > ln){
            if(toLeft){ pr(s, ln);              prSpace(width - ln, ' ');  }
            else      { prSpace(width - ln, zero ? '0' : ' '); pr(s, ln);  }
        }   else      { pr(s, ln);                                         }

      }else{        /* Отрицательное число */
        if(width > ln){
            /* Надо заполнять оставшуюся часть поля */

            width -- ; /* width содержит одну позицию для минуса */
            if(toLeft){ putchar('-'); pr(s, ln); prSpace(width - ln, ' ');  }
            else{
                    if( ! zero ){
                            prSpace(width - ln, ' '); putchar('-'); pr(s,ln);
                    } else {
                            putchar('-'); prSpace(width - ln, '0'); pr(s, ln);
                    }
            }
        }   else    {       putchar('-'); pr(s, ln);   }
      }
    }

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

    /* --------------------------------------------------------- */
    main(){
            int i, n;
            static char s[] = "Hello, world!\n";
            static char p[] = "Hello, world";
            long t = 7654321L;

            myprintf( "%%abc%Y\n");
            myprintf( "%s\n",        "abs" );
            myprintf( "%5s|\n",       "abs" );
            myprintf( "%-5s|\n",      "abs" );
            myprintf( "%5s|\n",       "xyzXYZ" );
            myprintf( "%-5s|\n",      "xyzXYZ" );
            myprintf( "%5.5s|\n",     "xyzXYZ" );
            myprintf( "%-5.5s|\n",    "xyzXYZ" );
            myprintf( "%r\n",       444 );
            myprintf( "%r\n",       999 );
            myprintf( "%r\n",       16 );
            myprintf( "%r\n",       18 );
            myprintf( "%r\n",       479 );
            myprintf( "%d\n",  1234 );
            myprintf( "%d\n",  -1234 );
            myprintf( "%ld\n",  97487483 );
            myprintf( "%2d|%2d|\n",   1, -3 );
            myprintf( "%-2d|%-2d|\n", 1, -3 );
            myprintf( "%02d|%2d|\n",   1, -3 );
Предыдущая страница Следующая страница
1 ... 14 15 16 17 18 19 20  21 22 23 24 25 26 27 ... 87
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 

Реклама