Я работаю над книгой K & R. Я читал дальше, чем делал упражнения, в основном из-за нехватки времени. Я догоняю и выполнил почти все упражнения из главы 1, которая является учебным пособием.
Моим вопросом было упражнение 1-18. Упражнение заключается в:
Напишите программу для удаления конечных пробелов и
вкладки из строки ввода, и удалить полностью пустые строки
Мой код (ниже) делает это и работает. Моя проблема с этим - метод отделки, который я реализовал. Это кажется ... неправильно ... как-то. Например, если бы я видел подобный код в C # в обзоре кода, я бы, наверное, сошел с ума. (C # одна из моих специальностей.)
Может кто-нибудь предложить какой-нибудь совет по очистке этого - с уловкой, которая сказала, что совет должен использовать только знания из Главы 1 K & R. (Я знаю, что есть миллионы способов очистить это, используя полную библиотеку C ; мы просто говорим здесь о главе 1 и базовом stdio.h.) Также, когда вы даете совет, можете ли вы объяснить, почему он поможет? (В конце концов, я пытаюсь учиться! А у кого лучше учиться, чем у экспертов здесь?)
#include <stdio.h>
#define MAXLINE 1000
int getline(char line[], int max);
void trim(char line[], char ret[]);
int main()
{
char line[MAXLINE];
char out[MAXLINE];
int length;
while ((length = getline(line, MAXLINE)) > 0)
{
trim(line, out);
printf("%s", out);
}
return 0;
}
int getline(char line[], int max)
{
int c, i;
for (i = 0; i < max - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
line[i] = c;
if (c == '\n')
{
line[i] = c;
++i;
}
line[i] = '\0';
return i;
}
void trim(char line[], char ret[])
{
int i = 0;
while ((ret[i] = line[i]) != '\0')
++i;
if (i == 1)
{
// Special case to remove entirely blank line
ret[0] = '\0';
return;
}
for ( ; i >= 0; --i)
{
if (ret[i] == ' ' || ret[i] == '\t')
ret[i] = '\0';
else if (ret[i] != '\0' && ret[i] != '\r' && ret[i] != '\n')
break;
}
for (i = 0; i < MAXLINE; ++i)
{
if (ret[i] == '\n')
{
break;
}
else if (ret[i] == '\0')
{
ret[i] = '\n';
ret[i + 1] = '\0';
break;
}
}
}
РЕДАКТИРОВАТЬ: Я ценю все полезные советы, которые я вижу здесь. Я хотел бы напомнить людям, что я все еще n00b с C, и, в частности, еще не дошел до указателей. (Вспомните немного о Ch.1 в K & R - в Ch.1 нет указателей.) Я "вроде" получаю некоторые из этих решений, но они все еще немного продвинуты для того, где я нахожусь ...
И большая часть того, что я ищу, - это сам метод обрезки, в частности тот факт, что я повторяю циклы 3 раз (что кажется таким грязным). Я чувствую, что если бы я был чуть более умным (даже без глубоких знаний C), это могло бы быть чище.