C ++ printf: новая строка (\ n) из аргумента командной строки - PullRequest
1 голос
/ 24 марта 2010

Как строка формата печати передается в качестве аргумента?

example.cpp:

#include <iostream> 
int main(int ac, char* av[]) 
{
     printf(av[1],"anything");
     return 0;
}

попробовать:

example.exe "print this\non newline"

вывод:

print this\non newline

вместо этого я хочу:

print this
on newline

Ответы [ 7 ]

7 голосов
/ 24 марта 2010

Нет, не делай этого!Это очень серьезная уязвимость.Вы никогда не должны принимать строки формата в качестве входных данных.Если вы хотите печатать новую строку всякий раз, когда видите «\ n», лучшим подходом будет:

#include <iostream>
#include <cstdlib>

int main(int argc, char* argv[])
{
     if ( argc != 2 ){
         std::cerr << "Exactly one parameter required!" << std::endl;
         return 1;
     }

     int idx = 0;
     const char* str = argv[1];
     while ( str[idx] != '\0' ){
          if ( (str[idx]=='\\') && (str[idx+1]=='n') ){
                 std::cout << std::endl;
                 idx+=2;
          }else{
                 std::cout << str[idx];
                 idx++;
          }
     }
     return 0;
}

Или, если вы включите библиотеки Boost C ++ в свой проект, вы можете использоватьboost::replace_all функция для замены экземпляров "\\ n" на "\ n", как предлагает Pukku.

2 голосов
/ 24 марта 2010

По крайней мере, если я правильно понимаю, вы действительно задаетесь вопросом о преобразовании escape-последовательности "\ n" в символ новой строки. Это происходит во время компиляции, поэтому, если (например) вы введете «\ n» в командной строке, он будет напечатан как «\ n» вместо преобразования в символ новой строки.

Я написал код лет назад, чтобы преобразовать escape-последовательности, когда вы этого хотите. Пожалуйста, не передавайте это как первый аргумент для printf. Если вы хотите напечатать введенную пользователем строку, используйте fputs или формат преобразования "% s":

int main(int argc, char **argv) { 
    if (argc > 1) 
        printf("%s", translate(argv[1]));
    return 0;
}
1 голос
/ 24 марта 2010

передача пользовательских аргументов непосредственно в printf вызывает уязвимость, называемую «атака формата строки»

См. Википедия и Подробнее

1 голос
/ 24 марта 2010

Вы не можете сделать это, потому что \n и т.п. анализируются компилятором C. В сгенерированном коде записывается фактическое числовое значение.

Это означает, что ваша входная строка должна фактически содержать символьное значение 13 (или 10 или оба), чтобы считаться новой строкой, поскольку функции C не знают, как обрабатывать эти специальные символы, поскольку Компилятор C делает это за них .

В качестве альтернативы вы можете просто заменить каждый экземпляр \\n на \n в вашей строке перед отправкой на printf.

0 голосов
/ 13 февраля 2013

Я знаю ответ, но активна ли эта тема? кстати

можешь попробовать example.exe "напечатать этот $ (echo -e" \ n ") на новой строке".

Я пытался и казнил С Уважением, Шахид nx

0 голосов
/ 24 марта 2010

Только компилятор преобразует \ n и т. Д. В действительный символ ASCII, когда находит эту последовательность в строке.

Если вы хотите сделать это для строки, которую вы откуда-то получаете, вам нужно напрямую обработать строку и заменить строку "\ n" на CR / LF и т. Д. И т. Д.

Если вы сделаете это, не забывайте, что "\\" тоже становится "\".

Пожалуйста, никогда не используйте буферы char * в C ++, есть хороший класс std :: string, который безопаснее и элегантнее.

0 голосов
/ 24 марта 2010

Нет способа автоматически получить строку, содержащую символ новой строки. Вам придется самостоятельно выполнить какую-то замену строки, прежде чем использовать параметр.

...