Я долго думал над этим упражнением, но к сожалению не смог его решить ((
Наученный опытом опечаток во время перевода, я глянул на текст оригинала.
Перевод:
Перепишите main предыдущей программы так, чтобы она могла печатать самую длинную строку без каких-либо ограничений на ее размер.
Оригинал:
Revise the main routine of the longest-line program so it will correctly print the length of arbitrary long input lines, and as much as possible of the text.
Итак, задача упрощается, необходимо напечатать правильную длину строки и как можно больше содержимого этой строки при условии, что сама строка может быть длиннее максимального размера вводимой строки, определенного как MAXLINE. Только непонятно, что подразумевается под main routine, все-таки функция main или главная процедура (рутина) самой программы.
Переписать функцию main оказалось не так просто. Поэтому, для начала перепишем функцию getstr, которая читает строку из текстового потока и будет возвращать ее правильную длину.
Механизм использования функции в Си удобен, легок и эффективен.<Enter>
Нередко вы будете встречать короткие функции, вызываемые лишь единожды; они оформлены в виде функции с одной-единственной целью — получить более ясную программу.<Enter>
<Ctrl>+<D>
Длина самой длинной строки равна 162 символа(ов)
Нередко в
Для проверки точности полученного результата используем программу wc (print newline, word, and byte counts for each file), о которой упоминалось на 36 странице книги.
<Ctrl>+<D>
162 -
Снова возвращаемся к функции main. Алгоритм решения упражнения, по условию которого необходимо измененить функцию main, приведен на рисунке ниже.
#include <stdio.h>
#define MAXLINE 10 /* максимальный размер вводимой строки */
int getstr(char line[], int maxline);
void copy(char to[], char from[]);
int main(void)
{
int len; /* длина текущей строки */
int max; /* длина максимальной из просмотренных строк */
char line[MAXLINE]; /* текущая строка */
char longest[MAXLINE]; /* самая длинная строка */
/* Сигнализировать о том, что текстовый поток имеет длину
* более, чем объявлено в MAXLINE
wait = 0;
int iNt; /* промежуточная длина текстового потока */
iNt = 0;
int i; /* для for-цикла */
for (i = 0; i < MAXLINE; ++i)
line[i] = longest[i] = temp[i] = 0;
max = 0;
/* есть ли еще строка */
while ((len = getstr(line, MAXLINE)) > 0 )
{
if(line[len-1] != '\n')
{
if (wait == 0)
copy(temp, line);
iNt = iNt + len;
if (max < iNt)
max = iNt;
wait = 1;
}
else
{
if (wait == 1)
{
if (max < (iNt + len))
{
max = iNt + len;
copy(longest, temp);
}
wait = 0;
}
else if (len > max)
{
max = len;
copy(longest, line);
}
iNt = 0;
}
}
if (max > 0) /* была ли хоть одна строка? */
{
printf("%s\n", longest);
return 0;
}
/* getstr: читает строку в s, возвращает длину */
int getstr(char s[], int lim)
{
int c, i;
Переписать функцию main оказалось не так просто. Поэтому, для начала перепишем функцию getstr, которая читает строку из текстового потока и будет возвращать ее правильную длину.
$ vim ex_1_16_4.c
#include <stdio.h>
#define MAXLINE 10 /* уменьшим до 10 размер строки */
int getstr(char line[], int maxline);
void copy(char to[], char from[]);
int main(void)
{
int len; /* длина текущей строки */
int max; /* длина максимальной из просмотренных строк */
char line[MAXLINE]; /* текущая строка */
char longest[MAXLINE]; /* самая длинная строка */
int i;
for (i = 0; i < MAXLINE; ++i)
line[i] = longest[i] = 0;
max = 0;
/* есть ли еще строка */
while ((len = getstr(line, MAXLINE)) > 0 )
{
if (len > max)
{
max = len;
copy(longest, line);
}
}
if (max > 0) /* была ли хоть одна строка? */
{
printf("Длина самой длинной строки равна %d символа(ов)\n", max);
printf("%s\n", longest);
}
return 0;
}
/* getline: читает строку в s, возвращает длину */
int getstr(char s[], int lim)
{
int c;
int i; /* длина строки */
int index; /* индекс массива s[] */
/* Убираем ограничение на длину строки в for-цикле */
for (i = 0, index = 0; (c = getchar()) != EOF && c != '\n'; ++i)
{
/* i продолжает расти при вводе символов
* даже если массив s[] "почти" полон*/
if (i < lim - 1)/* массив s[] не должен превышать MAXLINE */
{
s[index] = c; /* наполнение массива s[] символами */
++index;
}
}
if (c == '\n')
{
s[index] = c;
++index;
++i;
}
s[index] = '\0'; /* в конец строки дописывам "0" */
return i; /* функция возвращает длину строки */
}
/* copy: копирует из 'from' в 'to'*/
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
$ cc -g -O0 -Wall -o a.out ex_1_16_4.c
$ ./a.outДо сих пор мы пользовались готовыми функциями вроде main, getchar и putchar, теперь настала пора нам самим написать несколько функций.<Enter>
Механизм использования функции в Си удобен, легок и эффективен.<Enter>
Нередко вы будете встречать короткие функции, вызываемые лишь единожды; они оформлены в виде функции с одной-единственной целью — получить более ясную программу.<Enter>
<Ctrl>+<D>
Длина самой длинной строки равна 162 символа(ов)
Нередко в
Для проверки точности полученного результата используем программу wc (print newline, word, and byte counts for each file), о которой упоминалось на 36 странице книги.
$ wc -m -Нередко вы будете встречать короткие функции, вызываемые лишь единожды; они оформлены в виде функции с одной-единственной целью — получить более ясную программу.<Enter>
<Ctrl>+<D>
162 -
Снова возвращаемся к функции main. Алгоритм решения упражнения, по условию которого необходимо измененить функцию main, приведен на рисунке ниже.
#include <stdio.h>
#define MAXLINE 10 /* максимальный размер вводимой строки */
int getstr(char line[], int maxline);
void copy(char to[], char from[]);
int main(void)
{
int len; /* длина текущей строки */
int max; /* длина максимальной из просмотренных строк */
char line[MAXLINE]; /* текущая строка */
char longest[MAXLINE]; /* самая длинная строка */
char temp[MAXLINE]; /* для временного хранения фрагмента потока */
/* Сигнализировать о том, что текстовый поток имеет длину
* более, чем объявлено в MAXLINE
* wait = 1 - предыдущий фрагмент потока больше MAXLINE
* wait = 0 - предыдущий фрагмент потока меньше или равен MAXLINE*/
int wait;wait = 0;
int iNt; /* промежуточная длина текстового потока */
iNt = 0;
int i; /* для for-цикла */
for (i = 0; i < MAXLINE; ++i)
line[i] = longest[i] = temp[i] = 0;
max = 0;
/* есть ли еще строка */
while ((len = getstr(line, MAXLINE)) > 0 )
{
if(line[len-1] != '\n')
{
if (wait == 0)
copy(temp, line);
iNt = iNt + len;
if (max < iNt)
max = iNt;
wait = 1;
}
else
{
if (wait == 1)
{
if (max < (iNt + len))
{
max = iNt + len;
copy(longest, temp);
}
wait = 0;
}
else if (len > max)
{
max = len;
copy(longest, line);
}
iNt = 0;
}
}
if (max > 0) /* была ли хоть одна строка? */
{
printf("%s\n", longest);
printf("Длина самой длинной строки %d символа(ов)\n", max);
}return 0;
}
/* getstr: читает строку в s, возвращает длину */
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'; /* в конец строки дописывам "0" */
return i; /* функция возвращает длину строки */
}
/* copy: копирует из 'from' в 'to'; to достаточно большой */
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
Комментариев нет:
Отправить комментарий