понедельник, 20 января 2014 г.

Упражнение 1.20.

Перевод: Напишите программу detab, заменяющую символы табуляции во вводимом тексте нужным числом пробелов (до следующего "стопа" табуляции). Предполагается, что "стопы" табуляции расставлены на фиксированном расстоянии друг от друга, скажем, через n позиций. Как лучше задавать n - в виде значения переменной или в виде именованной константы?

Оригинал: Write a program detab that replaces tabs in the input with the proper number of blanks to space to the next tab stop. Assume a fixed set of tab stops, say every n columns. Should n be a variable or a symbolic parameter?

    Количество пробелов до следующего "стопа" будем получать по алгоритму: от расстояния между стопами отнимаем результат остатка от деления позиции символа табуляции на расстояние между "стопами". Предположим, что "стопы" табуляции расположены на расстоянии пяти позиций друг от друга.
    Пусть 7-й символ будет символом табуляции. Арифметическая операция остаток от деления 7 % 5 = 2, а 5 - 2 = 3. Получаем, что до следующего "стопа" табуляции остается 3 позиции.


7 % 5 = 2
7 = 5 * 1 + 2

    Пусть 11-й символ будет символом табуляции. Арифметическая операция остаток от деления 11 % 5 = 1, а 5 -1 = 4. Получаем, что до следующего "стопа" табуляции остается 4 позиции.
11 % 5 = 1
11 = 5 * 2 + 1
 $ vim ex_1_20.c
#include <stdio.h>
#define MAXLINE 1000    /* максимальный размер вводимой строки */
#define STOP 5          /* расстояние "стопов" табуляции друг от друга */

int getstr(char line[], int maxline);

int main(void)
{
    int len;
    char line[MAXLINE];
    int i, j;
    int symbols;        /* количество символов, выведенных на экран */
    int test = 0;       /* количество символов, выведенных на экран, до следующего "стопа" табуляции  */

    while((len = getstr(line, MAXLINE)) > 0)
    {
        for(i = 0, symbols = 0; line[i] != '\0'; ++i)
        {
            if(line[i] == '\t')
            {
                test = STOP - (symbols % STOP);

                for (j = 0; j < test; ++j)
                {
                    putchar('|');     /* для наглядности будем использовать символ '|' вместо пробела */
                    ++symbols;
                }
            }
            else
            {
                putchar(line[i]);
                ++symbols;
            }
        }
    }
    return 0;
}

int getstr(char s[], int lim)
{
    int c, i;
    for(i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
        s[i] = c;
    if(c == '\n')
    {
        s[i] = c;
        ++i;
    }
    s[i] = '\0';
    return i;

}
$ cc -g -O0 -Wall -o detab ex_1_20.c
$ ./detab
<Tab>
|||||
1<Tab>
1||||
11<Tab>
11|||
111<Tab>
111||
1111<Tab>
1111|
11111<Tab>
11111|||||

1 комментарий:

  1. #include
    #define n 5
    void tab(int count);
    int main(){
    int c, count;
    while((c=getchar())!=EOF) {
    ++count;
    if(c=='\t')
    tab(count);
    else
    putchar(c);
    }
    }
    void tab(int s){
    int l;
    if (s<5)
    s=s+5;
    l=s%n;
    l=(n+1)-l;
    while (l>0){
    printf("|");
    --l;
    }
    }

    ОтветитьУдалить