Напишите программу entab, заменяющую строки из пробелов минимальным числом табуляций и пробелов таким образом, чтобы вид напечатанного текста не изменился. Используйте те же "стопы" табуляции, что и в detab. В случае, когда для выхода на очередной "стоп" годится один пробел, что лучше — пробел или табуляция?
Write a program entab that replaces strings of blanks by the minimum number of tabs and blanks to achieve the same spacing. Use the same tab stops as for detab. When either a tab or a single blank would suffice to reach a tab stop, which should be given preference?
Алгоритм:
1. Запоминать на какой мы позиции;
2. Запоминать количество идущих подряд пробелов;
3. Если подряд идут четыре пробела, то сколько позиций остается до следующего "стопа" табуляции;
4. Делаем проход по всем элементам массива от нулевого и фиксируем номер позиции. Конец прохода (цикла) - символ '\0';
5. Если встречаем пробел (для наглядности меняем пробел на '_'), то увеличиваем счетчик пробелов ++space;
6. Если элемент массива не пробел, то сбрасываем счетчик пробелов;
7. Если количество подряд идущих пробелов равно четырем (количество пробелов в знаке табуляции), то узнаем сколько позиций до следующего стопа;
8. Смещаем оставшиеся символы влево на три позиции.
#include <stdio.h>
#define MAXLINE 1000
#define STOP 4 /* расстояние между "стопами" табуляции */
int getstr(char line[], int maxline);
int bstop(int position);
int main(void)
{
int len; /* длина символьного массива */
char line[MAXLINE]; /* символьный массив */
int i; /* позиция в символьном массиве */
int space; /* счетчик пробелов */
int before; /* количество позиций перед следующим "стопом" */
before = 0;
int j = 0;
while ((len = getstr(line, MAXLINE)) > 0)
{
printf("Длина строки равна %d\n", len);
for (i = 0, space = 0; line[i] != '\0'; ++i)
{
if (line[i] == '_') {
++space;
printf("Есть пробел. Сейчас подряд %d пробелов\n", space);
printf("Позиция в строке: %d\n", i);
}
else {
space = 0;
printf("Подряд пробелов нет\n");
printf("Позиция в строке: %d\n", i);
}
if (space == 4) {
printf("Есть ЧЕТЫРЕ пробела подряд!\n");
printf("Позиция в строке: %d\n", i);
before = bstop(i);
printf("До следующего \"стопа\" %d позиций\n", before);
i = i - (space - 1);
printf("Позиция, куда будет вставлен символ TAB: %d\n", i);
len = len - (space - 1);
printf("Длина строки короче на ТРИ символа и равна: %d\n", len);
line[i] = '\t';
for (j = i + 1; j < len; ++j)
line[j] = line[j + 3];
space = 0;
line[len] = '\0';
}
printf("\n");
}
printf("%s", line);
}
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;
}
int bstop(int i)
{
return STOP - (i % STOP) - 1;
}
#define MAXLINE 1000
#define STOP 4 /* расстояние между "стопами" табуляции */
int getstr(char line[], int maxline);
int bstop(int position);
int main(void)
{
int len; /* длина символьного массива */
char line[MAXLINE]; /* символьный массив */
int i; /* позиция в символьном массиве */
int space; /* счетчик пробелов */
int before; /* количество позиций перед следующим "стопом" */
before = 0;
int j = 0;
while ((len = getstr(line, MAXLINE)) > 0)
{
printf("Длина строки равна %d\n", len);
for (i = 0, space = 0; line[i] != '\0'; ++i)
{
if (line[i] == '_') {
++space;
printf("Есть пробел. Сейчас подряд %d пробелов\n", space);
printf("Позиция в строке: %d\n", i);
}
else {
space = 0;
printf("Подряд пробелов нет\n");
printf("Позиция в строке: %d\n", i);
}
if (space == 4) {
printf("Есть ЧЕТЫРЕ пробела подряд!\n");
printf("Позиция в строке: %d\n", i);
before = bstop(i);
printf("До следующего \"стопа\" %d позиций\n", before);
i = i - (space - 1);
printf("Позиция, куда будет вставлен символ TAB: %d\n", i);
len = len - (space - 1);
printf("Длина строки короче на ТРИ символа и равна: %d\n", len);
line[i] = '\t';
for (j = i + 1; j < len; ++j)
line[j] = line[j + 3];
space = 0;
line[len] = '\0';
}
printf("\n");
}
printf("%s", line);
}
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;
}
int bstop(int i)
{
return STOP - (i % STOP) - 1;
}
Примечание!
В данном решении я не смог сделать:
1. Чтобы напечатанный текст не менялся;
2. Я не обращаю внимание на "стопы" табуляции.
Комментариев нет:
Отправить комментарий