[cdev] Утилита Echo

Grigoriy A. Sitkarev sitkarev на komitex.ru
Ср Мар 17 17:02:45 MSK 2010


Отвечу по порядку.

Карабанова Елена пишет:
> Здравствуйте, 
> спасибо большое за вашу подсказку она очень мне помогла.

Я там забыл только второй обратный слеш нарисовать в условии (*c = '\\') 
но это  вы сообразили что ошибка и поправили.

> Функцию свою я вынесла за пределы main и изменила логику программы

Это я вижу.

Но стиль у вас не в порядке. Приведите пожалуйста так чтобы было приятно 
смотреть. Отступы у вас должны быть TAB-ами (а не пробелами), редактор 
настройте так, чтобы каждый TAB показывался как 8 пробелов. Вам будет 
удобно.

В функции main() у вас должны быть отступы:

int
main(int argc, char *argv[])
{
	int flags;
	int opt;
	...
}

А у вас их нет.

Не должно быть смешанных регистров в именах функций и идентификаторов.

Print_Words - не допустимо (do_echo бы подошло).

Почему-то уехали директивы препроцессора #include вправо. Там не надо 
отступов, они пишутся сразу:

#include <unistd.h>

> на текущий момент моя утилита понимает опции -e -E -n, но только если они идут сразу после команды 
> пример: 
> если написать echo2 -e 1234\\t123 выдаст 1234     123
> если написать echo2 -e -E 1234\\t123 выдаст 1234\t123
> если написать echo2 -e -E -n 1234\\t123 выдаст 1234\t123 но не перейдёт на новую строчку

Можете не расписывать подробно что делает ваша программа. Мне достаточно 
    вашего кода для этого. Не тратьте силы зря.

> а вот стандартная утилита echo если написать echo 1234 -e 5678 так и выведет 1234 -e 5678
> а моя утилита выведет 1234 5678

Не вижу в поведении вашей утилиты нарушения Open Group спецификации. ))

> не работает команда "\\" выдает ошибку если написать echo2 -e \\
> ORBIT_SOCKETDIR=/tmp/orbit-Elena

Она работает. Вам надо четыре обратных слеша потому что bash его 
использует как ESC-символ (два раза).

$ echo -e \\\\
\

> 
> не работает команда "\\с" проблема с реализацией 

В спецификации Open Group говорится что \c должна подавлять вывод 
символа новой строки \n. Все символы после \c должны игнорироваться. В 
чём проблема реализовать?

По умолчанию, у вас должен быть символ конца строки в выводе. Если 
встретится \c, то вы не должны его выводить. Так как вы пользуетесь 
форматированным вводом-выводом, то в конце должны делать fflush(3) на 
дескрипторе потока (хотя libc и флюшит все потоки при exit(1)).

Я бы сделал очень просто.

static int with_newline = 1; /* Enabled by default. */

...
while ((opt = getopt(...)) {
	switch (opt) {
	...
	case 'n':
		/* Disable output of newline. */
		with_newline = 0;
		break;
	...
	}
}

Потом вы в выводе используете эту переменную и если она не нулевая, то 
выводите символ новой строки.

	while (*c) {
        		if (*c == '\\') {
			c++;
                  	switch (*c) {
                  	case '\\':
				...
			case '\c':
				with_newline = 1;
				goto flush;
			}
		}
		...
	}
flush:
	if (with_newline)
		putc('\n');
	fflush(stdout);
	return;

Если вам встретилась команда '\c' то вы просто устанавливаете 
with_newline = 1 и немедленно переходите к метке flush (или обзовите её 
как считаете нужным) через goto.

Или изобразите нечто похожее, это не догма, так - мысли в слух.

> я вам посылаю исходный код, и откомпиллированный файл
> 
> у меня стоит Fedora12, а писала я программу в KDevelop: С/С++
> пробовала откомпиллировать исходный код в терминале, используя gcc откомпиллировалось успешно

Если в KDevelop компилируется то проверять отдельно "в терминале" не 
обязательно. KDevelop это только оболочка над gcc, binutils, gdb и т.д. 
Он на самом деле их запускает "в терминале" вы даже можете видеть их вывод.

--
Г.А.






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