[cdev] Утилита Echo

Grigoriy A. Sitkarev sitkarev на komitex.ru
Чт Мар 18 08:20:07 MSK 2010


Дизайн вашей программы очень сложный для такой простой задачи.

Вообще, я давно заметил что у наших учащихся есть такое стремление к 
необоснованному усложнению - не могу понять, откуда корни растут, может 
быть где-то ещё остались реликты эго "я такие программы пишу - НИКТО 
понять не может!". С другой стороны часто усложнение - это причина 
непонимания внутренних принципов языка или машины. Сделать сложно всегда 
проще чем сделать просто.

Я сейчас объясню.

Логика поведения echo такая:

1. По умолчанию не обрабатываются ESC-символы '\' и всегда вывод 
завершается символом '\n' (переход на новую строку).

2. Если задана опция -n то вывод символа новой строки отменяется.

3. Если задана опция -e то включается обработка ESC-символов '\'.

4. Существует опция -E которая отключает ESC-символы, т.е. её 
использование равнозначно поведению по умолчанию.

Вы начинаете делать какие-то сложнейшие пассы и манипуляции с подсчётом 
опций и т.д. Вам это всё не нужно. Всё гораздо проще. Переформулируем 
задачу.

1. ESC-символы могут обрабатываться (по умолчанию не обрабатываются).
2. Символ новой строки может выводиться (по умолчанию выводится).

Это значит что нам достаточно двух глобальных переменных, где мы будем 
хранить эти признаки (ДА/НЕТ) а программа должна модифицировать их 
значения при разборе опций.

int handle_escapes = 0;
int put_newline    = 1;

Сейчас эти глоб. переменные отражают переформулированные пункты 1 и 2 со 
значениями по умолчанию.

Дальше, когда вы в getopt(3) разбираете опции, то если вы встретите 
известные вам опции -e, -E, -n вы модифицируете эти переменные 
(включатете/выключаете handle_escapes или put_newline). Ничего там 
считать не надо. Если опции являются взаимоисключающими, как например -e 
и -E, то "побеждает" самая последняя переданная в аргументах.

$ echo -e -E -e -e -e -E -E -E -e -E "test me"

Здесь "победит" опция -E потому что она последняя была.

Вам нужно после разбора опций забрать остальную часть аргументов и 
интерпретировать как строки чтобы выводить на stdout. Тут тоже всё проще 
  должно быть. После того как вы закончили с getopt(3), вам всё что было 
в argv уже не нужно. Сделайте так:

argc -= optind;
argv += optind;

Теперь у вас в argv останутся (начиная с 0) остальные аргументы а в argc 
будет их количество.

Вы не понимаете областей видимости в Си. Поэтому задавали разные имена 
всем аргументам функций. Этого делать не надо, потому что в Си аргументы 
относятся к локальным переменным и эти имена не перекрываются у разных 
функций. В Си правила областей видимости очень простые, обратитесь к 
литературе, перечтите ещё раз соотв. главы.

Со стилем у вас всё ещё не порядок. Не все блоки имеют отступы, ещё раз 
внимательно всё пересмотрите. В принципе, switch я вам рекомендую 
выравнивать вот так:

switch (opt) {
case 'a':
	...
	break;
case 'b':
	...
	break;
}

Делать функции с именами типа do_echo2 - в вашем случае некорректно. 
Если в Linux например есть системный вызов mmap2(2), то это оправдано 
потому что он ничем не отличается от mmap(2), только во втором случае 
размер задаётся в байтах а в mmap2(2) в страницах. У вас же функции 
ведут себя по-разному, поэтому вам или надо их слить в одну или же 
назвать do_echo2 по-другому. Название функции должно отражать то что она 
делает иначе ваши программы будет трудно понимать.

Вам бы надо предусмотреть обработку случая когда пользователь ввёл 
неизвестную опцию. Вы должны в таком случае вывести краткую подсказку по 
использованию утилиты.

И на последок, можете не присылать бинарники сюда. Достаточно исходных 
файлов.

Что-то ещё вспомню, напишу.

--
Г.А.

Карабанова Елена пишет:
> Здравствуйте
> 
> я привела в порядок оформление текста исходного кода
> и сделала обработку команды "\\с"
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> cdev mailing list
> cdev на wiki.syktsu.ru
> http://wiki.syktsu.ru/cgi-bin/mailman/listinfo/cdev





Подробная информация о списке рассылки cdev