Cómo imprimir el formato de cadena que se pasa como argumento ?

example.cpp:

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

tratar:

example.exe "print this\non newline"

la salida es:

print this\non newline

lugar quiero:

print this
on newline
  • El hecho de que esta cuestión debe pedir en todas las muestra de una debilidad en el shell de comandos de Windows. En el shell de Unix, usted puede enviar el argumento de cadenas que contienen caracteres de salto de línea.
  • Mira esto: en.wikipedia.org/wiki/Format_string_attack Por hacer algo como printf(argv[1]); da al usuario la completa libertad para hacer su programa de hacer lo que el usuario quiere hacer. La pila puede ser impreso por el paso de «%08x» y la memoria se puede sobrescribir el uso de %n.
InformationsquelleAutor Sebtm | 2010-03-24

7 Comentarios

  1. 8

    No, no hagas eso! Que es un muy grave vulnerabilidad. Nunca debe aceptar cadenas de formato como de entrada. Si desea imprimir una nueva línea cada vez que usted vea un «\n», un mejor enfoque sería:

    #include <iostream> 
    #include <cstdlib> 
    
    int main(int argc, char* argv[]) 
    { 
    if ( argc != 2 ){ 
    std::cerr << "Exactamente un parámetro necesario!" << std::endl; 
    return 1; 
    } 
    
    int idx = 0; 
    const char* str = argv[1]; 
    mientras ( str[idx] != '
    #include <iostream> 
    #include <cstdlib> 
    int main(int argc, char* argv[]) 
    { 
    if ( argc != 2 ){ 
    std::cerr << "Exactamente un parámetro necesario!" << std::endl; 
    return 1; 
    } 
    int idx = 0; 
    const char* str = argv[1]; 
    mientras ( str[idx] != '\0' ){ 
    si ( (str[idx]=='\\') && (str[idx+1]=='n') ){ 
    std::cout << std::endl; 
    idx+=2; 
    }else{ 
    std::cout << str[idx]; 
    idx++; 
    } 
    } 
    return 0; 
    } 
    
    ' ){ si ( (str[idx]=='\') && (str[idx+1]=='n') ){ std::cout << std::endl; idx+=2; }else{ std::cout << str[idx]; idx++; } } return 0; }

    O, en el caso de incluir el Impulso de Bibliotecas de C++ en su proyecto, usted puede utilizar el boost::replace_all función para reemplazar las instancias de «\\n» con «\n», como sugiere Pukku.

    • /me se ejecuta el programa con un par de copias de %n en la cadena de formato…mmmm…. 😛
    • -1 Vulnerabilidad a un lado, ¿cómo es tu «respuesta», respondiendo el OP pregunta?
    • Cuidado de explicar?
    • Manta declaraciones también son peligrosas. Esto sería perfectamente bien en un ambiente donde usted tiene control sobre los parámetros, a través de archivo de proceso por lotes, por ejemplo.
    • Una que no es de confianza cadena de formato puede ser usado para alterar la memoria de formas arbitrarias. Por ejemplo, con la %n formato que he mencionado, escribe el número de la actualidad-escrito de caracteres en la dirección apuntada por el siguiente argumento. Ya que el atacante controla toda la cadena de formato (en este caso), también tienen un control de qué valor se pone por escrito. Incrustar un poco más %n y aún más garabatos.
    • usted podría pensar que usted tiene el control… pero hay que esperar hasta que termina en una gran base de código con otro código de la organización. ¿Tiene usted alguna idea de lo difícil que sería para realizar el seguimiento y evitar que caigan en algún otro lugar? Mejor no dejar que nunca introduzca su código base para empezar.

  2. 2

    Al menos si he entendido bien, usted pregunta es realmente acerca de la conversión de la «\n» secuencia de escape en una nueva línea de caracteres. Que sucede en tiempo de compilación, por lo que si (por ejemplo) entrar en el «\n» en la línea de comandos, se imprime como «\n» en lugar de ser convertido a una nueva línea de caracteres.

    Escribí algunos código años hace para convertir secuencias de escape cuando se desea que lo haga. Por favor, no pase como el primer argumento a printf, aunque. Si desea imprimir una cadena introducida por el usuario, utilice fputs, o el «%s» formato de conversión:

    int main(int argc, char **argv) { 
        if (argc > 1) 
            printf("%s", translate(argv[1]));
        return 0;
    }
  3. 1

    Usted no puede hacer eso porque \n y el como son analizadas por el compilador de C. En el código generado, el valor numérico que está escrito.

    Lo que esto significa es que su cadena de entrada tendrán que realmente contiene el valor del carácter de 13 años (o 10 o ambos) para ser considerada como una nueva línea debido a que las funciones C no saber cómo manejar estos caracteres especiales ya que el compilador de C no es para ellos.

    Alternativamente, usted puede reemplazar todas las instancias de \\n con \n en su cadena antes de enviarlo a printf.

  4. 0

    No hay forma de hacer que la cadena contiene un salto de línea. Usted tendrá que hacer algún tipo de cadena de reemplazar por su cuenta antes de que usted utilice el parámetro.

  5. 0

    Es sólo el compilador que convierte \n etc, hasta el real de caracteres ASCII cuando se considera que la secuencia de una cadena.

    Si quieres hacerlo de una cadena que se obtiene de algún lugar, usted necesita para manipular la cadena directamente y reemplazar la cadena «\n» con un CR/LF etc. etc.

    Si haces eso, no hay que olvidar que «\\» se convierte en ‘\’ demasiado.

    Por favor no usar nunca char* buffers en C++, no hay una buena clase std::string que es más seguro y más elegante.

  6. 0

    Sé la respuesta, pero es que este hilo está activo ?
    btw

    usted puede intentar
    example.exe «imprimir esta$(echo-e «\n «)en la nueva línea».

    He intentado y ejecutado
    Saludos,
    Shahid nx

Dejar respuesta

Please enter your comment!
Please enter your name here