2014-11-24 2 views
7

Я работал над примером в книге K & R C, где он просит по существу построить калькулятор RPN, который вводит ввод через аргументы командной строки. Мое решение по существу повторяется с помощью приведенных аргументов и выплескивает ответ, но я заметил что-то:argv: Санитирование подстановочных знаков

Если бы я должен был дать символ умножения (звездочка) '*' без одинарных кавычек, gcc предполагает, что это подстановочный знак, поэтому мой вход

$./rpn 5 10 * 

дает мне выход

read 5 
read 10 
read rpn 
read rpn.c 
= 0 

Обмотка звездочку одинарные кавычки средств этот вопрос

$./rpn 5 10 '*' 
read 5 
read 10 
read * 
= 50 

Мой вопрос заключается в том, будет ли способ дезинфицировать входные данные, чтобы моя программа не требовала, чтобы звездочка была обернута в одинарные кавычки, или это поведение вызвано чем-то более фундаментальным (например, Linux/POSIX/UNIX двоичное исполнение и обработка аргументов)?

+1

Чертовски хороший вопрос. – Qix

+1

Все, что связано с оболочкой; ничего общего с компилятором C вообще. Чтобы продемонстрировать, попробуйте написать небольшую программу: '#include ' и 'int main (void) {char * args [] = {" ./rpn "," 5 "," 10 "," * ", 0}; execv (args [0], args); return -1; } '. Оболочка обычно расширяет '*'; это позволяет избежать использования оболочки, поэтому расширение не происходит. –

+2

GCC ничего не знает. Оболочка - это тот, который подает вход в вашу программу. –

ответ

6

Оболочка расширяет glob перед выполнением программы. Вы указываете глобус не из-за GCC, а из-за оболочки. Если вы не хотите этого поведения, используйте оболочку, которая не соблюдает глобусы.

+0

Я вижу. Это может быть очень распространенной причиной неопределенного поведения, если вы не слишком осторожны с тем, что вводит разработчик, если они не принимают во внимание оболочку. Я полагаю, что в этом примере есть скрытый урок, и это должно учитывать тот часто игнорируемый уровень исполнения. – MSalmo

+1

На мой взгляд, на самом деле это не замечается. Вам просто нужно знать свои инструменты. –

+0

И это не «неопределенное поведение». Это прекрасно определено; это просто не то, что вы хотите здесь. – duskwuff

0

вход Дает в

$./rpn "5 10 *" 

Всего довод в "" и в программе вы получите все аргументы под argv[1] затем разобрать эту строку с помощью разделительного пространства.

Таким образом, вам необходимо обработать любой символ/специальный символ специальным образом.

+0

В качестве альтернативы вы относитесь ко всем персонажам с особым вниманием ... и усложняете программу 'rpn'. –

+0

, когда когда-либо какое-либо пространство входит в любые имена файлов/пути, которые задаются такой командной строкой argumemt, это создает проблему в linux и windows, поэтому другой способ обработки таких вещей обрабатывает все их как специальные –

+0

@ Mr.32 Я обычно соглашаюсь с вами, если сценарий был другим, однако это упражнение специально предназначалось для ввода для обработки в виде дискретных аргументов командной строки. – MSalmo

Смежные вопросы