Ситуация: У меня есть программа на C, которая принимает строковый аргумент и делает что-то полезное (подробности не актуальны.) Я хочу передать ему строку, содержащую контрольный символ, такой как EOF, CR или LF, и не может переключите мою клавиатуру в режим сырого ввода в терминале. Мой вопрос: имеет ли C функциональность, которая позволит мне указать или «набрать» символ каким-то образом? (Например, вы можете избегать символов с косой чертой или указывать свои шестнадцатеричные коды при создании строк на некоторых языках. Мне интересно, существует ли что-то подобное в отношении передачи аргументов программе C из терминала, поэтому я спрашиваю о аргументы командной строки.)Как передать управляющий или непечатаемый символ программе C?
ответ
В этой ситуации вам необходимо быть в курсе, где функциональность. Обработка может или не может быть выполнена интерпретатором командной строки, который вызывает вашу программу. Вы можете получать разные результаты от одного и того же кода C в зависимости от того, используете ли вы команду DOS или Linux или Unix и т. Д.
Какая оболочка используется, также может воздействовать на нее, а также параметры терминала. Подозреваю, нет «портативного» ответа на этот вопрос. –
Если вас устраивает возможность отправки escape-последовательностей в стиле строки C функция преобразования может работать для вас, если вы не используете кавычки в середине ввода. Если вам нужны кавычки в середине ввода, вам нужно выяснить, какую escape-последовательность использует ваша оболочка для передачи кавычек в командной строке args.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
// Unescapes 'str' in place, collapsing it back on itself, and
// returns the resulting length of the collapsed buffer. Handles
// mid-buffer nul characters (0x00). You can easily add your own
// special escape sequences if you wish. Just be sure that no escape
// sequence translates into more characters than it takes to encode
// the escape sequence itself in the original string.
int unescape(char* str)
{
char *out, *in;
int len=0;
in = out = str; // both start at the same place
while(*in)
{
char c = *in++;
if (c != '\\')
*out++ = c; // regular, unescaped character
else
{ // escaped character; process it...
c = *in++;
if (c == '0') *out++ = '\0';
else if (c == 'a') *out++ = '\a';
else if (c == 'b') *out++ = '\b';
else if (c == 'f') *out++ = '\f';
else if (c == 'n') *out++ = '\n';
else if (c == 'r') *out++ = '\r';
else if (c == 't') *out++ = '\t';
else if (c == 'v') *out++ = '\v';
else if (c == 'x' // arbitrary hexadecimal value
&& isxdigit(in[0]) && isxdigit(in[1]))
{
char x[3];
x[0] = *in++;
x[1] = *in++;
x[3] = '\0';
*out++ = strtol(x, NULL, 16);
}
else if (c>='0' && c<='3' // arbitrary octal value
&& in[0]>='0' && in[0]<='7'
&& in[1]>='0' && in[1]<='7')
{
*out++ = (c-'0')*64 + (in[0]-'0')*8 + (in[1]-'0');
in += 2;
}
else // any other char following '\' is just itself.
*out++ = *in++;
}
++len; // each time through the loop adds one character
}
*out = '\0';
return len;
}
void print_buf(const char* buf, int len)
{
int col;
unsigned char* cp = (unsigned char*)buf;
for (col=0; len>0; --len, ++col)
printf(" %02x%s", *cp++, ((col&16==15) ? "\n" : ""));
}
int main(int argc, char*argv[])
{
char* str;
int len;
if (argc<2)
{
fprintf(stderr, "First arg must be a string, "
"and it probably ought to be quoted.\n");
exit(1);
}
printf("\nInput string: \"%s\"\n", argv[1]);
print_buf(argv[1], strlen(argv[1]));
str = malloc(strlen(argv[1]));
strcpy(str, argv[1]);
len = unescape(str);
printf("\nunescape() produces the following:\n");
print_buf(str, len);
free(str);
printf("\n");
}
Возможно, вам захочется узнать, как передавать двоичные данные в качестве аргумента в bash. См. this question.
Вот короткая демонстрация на C. Программа печатает каждый переданный ей аргумент, символ по символу, в шестнадцатеричном формате.
/* compile with cc -o binarg binargs.c */
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
char *ip;
printf("\n");
for(i=0; i<argc; i++)
{
printf("argv[%d]=%s\n",i,argv[i]);
for(ip=(char*)argv[i]; *ip!=0; ip++)
{
printf("0x%02X <-\t`%c'\n",*ip,*ip);
}
printf("\n");
}
return 0;
}
давайте передадим ему двоичные аргументы, как указано в сообщении, упомянутом выше.
./binargs ABC $'\x41\x42\x43' $'\t\n'
результаты:
argv[0]=./binargs 0x2E <- `.' 0x2F <- `/' 0x62 <- `b' 0x69 <- `i' 0x6E <- `n' 0x61 <- `a' 0x72 <- `r' 0x67 <- `g' 0x73 <- `s' argv[1]=ABC 0x41 <- `A' 0x42 <- `B' 0x43 <- `C' argv[2]=ABC 0x41 <- `A' 0x42 <- `B' 0x43 <- `C' argv[3]= 0x09 <- ` ' 0x0A <- ` '
ARGV [0] это имя нашей программы binargs
самой
ARGV [1] является регулярной строкой "ABC"
argv [2] совпадает с argv [1], но в шестнадцатеричном формате
ARGV [3] является sequense из двух управляющих символов: HT LF
Обратите внимание, что она использует традиционный способ Unix цитировать каждый символ, поэтому мы можем видеть границу непечатаемых символов при печати:
./binargs $'\a\b\v\f'
(давайте пропустить ARGV [0] часть)
argv[1]= 0x07 <- `' 0x08 <- ' 0x0B <- ` ' 0x0C <- ` '
или мы можем конвейеру к cat -v
./binargs $'\a\b\v\f' | cat -v
, что делает результат более читаемым:
argv[1]=^G^H^K^L 0x07 <- `^G' 0x08 <- `^H' 0x0B <- `^K' 0x0C <- `^L'
- 1. Как преобразовать непечатаемый символ или строку в шестнадцатеричный?
- 2. Как искать и заменять непечатаемый символ
- 3. Как назначить непечатаемый символ ascii переменной char
- 4. как grep ASCII управляющий символ
- 5. GNU Fortran - управляющий символ case
- 6. Заменить управляющий символ в строке C#
- 7. Редактор ACE удаляет управляющий символ
- 8. zsh - подсказка набирает управляющий символ
- 9. Отправить непечатаемый символ двоичный смс в android
- 10. Обнаружение, если найден непечатаемый символ - Perl
- 11. Как узнать непечатаемый символ с помощью команды unix vi
- 12. управляющий поток в программе рубинового волокна
- 13. Perl Expect.pm отправить управляющий символ в подпроцесс
- 14. Как отправить символ ASCII в программе C#
- 15. Как найти непечатаемый символ в строке в базе данных доступа?
- 16. Как передать аргументы командной строки программе c
- 17. java.lang.IllegalArgumentException: управляющий символ в значении или атрибуте cookie
- 18. Как отправить управляющий символ Ctrl-C или сообщение о зависании терминала дочернему процессу?
- 19. Есть ли управляющий символ для запуска принтера?
- 20. Sublime Text, возвращающий nul управляющий символ
- 21. Jsch: Есть ли способ отправить управляющий символ
- 22. Управляющий ключ + символ не обрабатывается в IE
- 23. C#, управляющий панелью
- 24. Класс процесса непечатаемый эхо-выход C#
- 25. Может ли bash использовать непечатаемый символ в качестве цитаты?
- 26. Как обнаружить этот непечатаемый символ с помощью регулярного выражения или других способов в Ruby?
- 27. Как передать символ * от C до CPP?
- 28. Непечатаемый (0xFF) байт в исходном файле C++
- 29. Специальный символ в программе
- 30. Как передать символ asterisk '*' в bash в качестве аргументов моей программе на C?
Есть, как правило, горячие клавиши для этого (Ctrl + D = EOF, и т.д ...) проверить приложение терминала для соответствующего из них. Или если вы имеете в виду передачу фактического символа в C-строке, вы можете просто ввести его в c-строку, используя его литерал («\ r», «\ n» и т. Д.). –
Я имею в виду аргумент командной строки. И проблема с горячими клавишами заключается в том, что, если я не в сыром режиме, они не набирают символ. Например, Ctrl + D фактически выходит из любой программы, в которой я находится. – mage
Возможно, это не лучшие способы обработки вещей в вашей программе, если вам требуются многие из этих управляющих символов. –