Страницы

Translate

воскресенье, 21 июля 2013 г.

Упражнение 1.22. Напишите программу, печатающую символы входного потока так, чтобы строки текста не выходили правее n-й позиции.

Упражнение 1.22. Напишите программу, печатающую символы входного потока так, чтобы строки текста не выходили правее n-й позиции. Это значит, что каждая строка, длина которой превышает n, должна печататься с переносом на следующие строки. Место переноса следует "искать" после последнего символа, отличного от символа-разделителя, расположенного левее n-й позиции. Позаботьтесь о том, чтобы ваша программа вела себя разумно в случае очень длинных строк, а также когда до n-й позиции не встречается ни одного символа пробела или табуляции.

#include <stdio.h>
#define TAB 8
#define LEN 10

void print_line(int symv);
int search_space(int symv);
int search_newsymv(int symv);
char line[LEN];

int main()
{
    int c, symv;
    
    symv=0;
    while((c=getchar()) != EOF)
    {
        line[symv]=c;
        if(c=='\t')
        {
            line[symv]=' ';
            for(symv++; symv<LEN && symv%TAB != 0; symv++)
                line[symv]=' ';
            if(symv>=LEN)
                print_line(symv);                
        }
        if(c=='\n')
        {
            print_line(symv);
            symv=0;
        }
        else
        {
            if(symv++>=LEN)
            {
                symv=search_space(symv);
                print_line(symv);
                symv=search_newsymv(symv);
            }
        }
    }
    return 0;
}

/*печать строки*/
void print_line(int symv)
{
    int i;
    for(i=0; i<symv; i++)
        putchar(line[i]);
    if(symv>0)
        putchar('\n');
}

/*поиск пробела*/
int search_space(int symv)
{
    while(line[symv] !=' ' && symv>0)
        symv--;
    if(symv==0)
        return LEN;
    else
        return symv++;
}

/*поиск места размещения симdола
 * в новой строке*/
int search_newsymv(int symv)
{
    int i, j;
    if(symv<=0 || symv>=LEN)
        return 0;
    else
    {
        i=0;
        for(j=symv++; j<LEN; j++)
        {
            line[i] = line[j];
            i++;
        }
        return i;
    }
}


Результат:


суббота, 20 июля 2013 г.

Упражнение 1.21. Напишите программу entab, заменяющую строки из пробелов минимальным числом табуляций и пробелов

Упражнение 1.21. Напишите программу entab, заменяющую строки из пробелов минимальным числом табуляций и пробелов таким образом, чтобы вид напечатанного текста не изменился. Используйте те же "стопы" табуляции, что и в detab. В случае, когда для выхода на очередной "стоп" годится один пробел, что лучше — пробел или табуляция?( Я думаю лучше пробел).


/*entab*/

#include <stdio.h>
#define TAB 8

int main()
{
    int c, ntab, nspace, symv;
    
    symv=1;
    ntab=0;//табуляции
    nspace=0;//пробелы
    while((c=getchar()) != EOF)
    {
        symv++;
        if(c==' ')
        {
            if(symv%TAB==0)
            {
                ntab++;
                nspace=0;
            }
            else
                nspace++;
        }
        else
        {
             while(ntab>0)
            {
                putchar('\t');
                ntab--;
            }
            if(c=='\t')
            {
                nspace=0;
                putchar('\t');
                symv=symv+(TAB-(symv%TAB));
            }
            else
            {
                while(nspace>0)
                {
                    putchar(' ');
                    nspace--;
                }
                putchar(c);
                if(c=='\n')
                {
                    symv=0;
                    ntab=0;
                    nspace=0;
                }
            }
        }
    }
    return 0;
}


Результат:




Упражнение 1.20. Напишите программу detab, заменяющую символы табуляции во вводимом тексте нужным числом пробелов

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

n лучше задать в виде именованной константы.

/*detab*/

#include <stdio.h>
#define TAB 8

int main()
{
int c, i, symvol, ntab;
    
symvol=1;//количество введённых символов до табуляци
while((c=getchar()) != EOF)
{
if(c=='\t')
{
//определяем количество пробелов
//нужных для вставки
ntab = TAB - (symvol-1);
for(i=0; i<ntab; i++)
putchar('|');//тут должен стоять пробел
symvol=0;
}
else if(c=='\n')
{
symvol=0;
printf("\n");
}
else
putchar(c);
symvol++;
            if(symvol==TAB)
                symvol=0;
}
return 0;
}

Для большей наглядности вместо пробелов использую символ ' | '
Результат:  


пятница, 12 июля 2013 г.

Упражнение 1.19. Напишите функцию reverse(s), размещающую символы в строке s в обратном порядке.


Упражнение 1.19. Напишите функцию reverse(s), размещающую символы в строке s в обратном порядке.
Примените ее при написании программы, которая каждую вводимую строку располагает в обратном порядке.


#include <stdio.h>
#define MAX 1000

void reverse(char s[], int n);
int main(int argc, char **argv)
{
    
    char line[MAX];
    int i, m;
    char c;
    i=0;
    while((c=getchar()) != EOF)
    {
        line[i]=c;
        i++;
        if(c=='\n')
        {
            line[i]='\0';
            m=i;//запоминаем длину введённой строки
            i=0;
            reverse(line, m);
            printf("%s\n", line);
        }
    }
    return 0;
}

void reverse(char s[], int n)
{
    char tmp[MAX];
    int i, j;
    for(i=0; i<n; i++)
        tmp[i]=s[i];
    i-=2;//отнимаем символ \0, и ещё один элемент 
    //из-за правил нумерации массива
    for(j=0; j<(n-1); j++, i--)
        s[j]=tmp[i];
}

Результат:



Упражнение 1.18. Напишите программу, которая будет в каждой вводимой строке заменять стоящие подряд символы пробелов и табуляций на один пробел и удалять пустые строки.


Упражнение 1.18.  Напишите программу, которая будет в каждой вводимой строке заменять стоящие подряд символы пробелов и табуляций на один пробел и удалять пустые строки.
В оригинале звучит так - Напишите программу, чтобы удалить завершающие пробелы и символы табуляции в каждой строке ввода, и чтобы полностью удалить пустые строки.


#include <stdio.h>
#define MAXLINE 1000 // максимальный размер вводимой строки

int getlin(char line[], int MAX);

int main()
{
    int len, i; //длина текущей строки, переменная
    char line[MAXLINE]; //текущая строка
    while((len=getlin(line, MAXLINE))>0)
    {
      len-=1;//отнимаем '\0'
      //уменьшаем строку, убирая пробелы и табуляции 
      for(i=len-1; i>=0; i--)
         if(line[i]=='0' || line[i]=='1')
            len--;
         else i=0;
       if (len!=0)//если строка не пустая выводим её
      {
         for(i=0; i<len; i++)
            printf("%c", line[i]);
         printf("\n");
      }
    }
    return 0;
}

/*getline читает строку в s, возвращает длину*/
int getlin(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;
}

Для наглядности вместо лишних пробелов будут нули, 1 вместо табуляции.
Результат:



Упражнение 1.17. Напишите программу печати всех вводимых строк, содержащих более 80 символов.

Упражнение 1.17. Напишите программу печати всех вводимых строк, содержащих более 80 символов. (Чтобы было легче - более 10 символов).


#include <stdio.h>
#define MAXLINE 1000 // максимальный размер вводимой строки

int getlin(char line[], int MAX);

/*печать строки длинной больше 10 символов*/
int main()
{
    int len; //длина текущей строки
    char line[MAXLINE]; //текущая строка
    while((len=getlin(line, MAXLINE))>0)
      if((len-1)>10)
         printf("Эта строка больше 10 символов: %s\n", line);
    return 0;
}

/*getline читает строку в s, возвращает длину*/
int getlin(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;
}


Результат:


Упражнение 1.16. Перепишите main предыдущей программы так, чтобы она могла печатать самую длинную строку без каких-либо ограничений на ее размер.

Упражнение 1.16.
В русском варианте перевод какой-то неточный, дословно перевод говорит, что надо определить длину вводимой строки, вывести её на экран и напечатать часть текста(которая входит в диапазон массива).


#include <stdio.h>
#define MAXLINE 10 // максимальный размер вводимой строки

int getlin(char line[], int MAX);
void copy(char to[], char from[]);


/*печать самой длинной строки*/
int main()
{
    int len; //длина текущей строки
    int max; //длина максимальной из просмотренных строк
    char line[MAXLINE]; //текущая строка
    char longest[MAXLINE]; //самая длинная строка
    int c;
    max=0;
    while((len=getlin(line, MAXLINE))>0)
    {
        if(line[len-1] != '\n')
            while((c=getchar())!=EOF && c!='\n')
            len++;
      if(len>max)
        {
            max=len;
            copy(longest, line);
        }
    }
    if(max<MAXLINE) // вычитаем нулевой символ вставленный в getlin
      max--;
   if(max>0)
   {
      printf("Самая длинная строка\n");
      if(max>MAXLINE)
         printf("%s...\n", longest);
      else
         printf("%s\n", longest);
    }
    printf("длинa строки - %d символов\n", max);
     return 0;
}

/*getlin читает строку в s, возвращает длину*/
int getlin(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;
}

void copy(char to[], char from[])
{
    int i;
    i=0;
    while((to[i] = from[i]) != '\0')
        i++;
}



Результат: