2012-02-24 13 views
5

este código:cadena de impresión sin personajes escapan

void Controller::write(const std::string& str) { 
    std::cout << "Writing: [" << str << "] to board." << std::endl; 
    s.write(str); 

toma una string y lo empuja a través de una conexión serie a un microcontrolador. (Esto funciona bien). Sin embargo, cuando trato de empujar una como esta: write("ats203?\r"), la salida de la consola se ve así:

] to board.ts203? 

Así que la Writing: [a se sobreescribe por el ] to board. después std::cout se encuentra con el \r en la cadena.

¿Cómo puedo imprimir la cadena como un grupo de caracteres en lugar de modificar la salida de la consola cuando se encuentra un carácter de escape?

EDITAR: Para aclarar.

I quiero mi cadena es ats203?\r. Esto se debe a que el microcontrolador se controla utilizando una versión ligeramente modificada de AT command, y no acepta el comando hasta que lee \r. Cuando se presiona la cadena hacia el microcontrolador, se lee \r como un retorno de carro, y actúa sobre cosas que lee antes del \r.

Lo que quiero es mostrar la cadena que he construido. Hay un montón de otros comandos en otros lugares que se crean dependiendo de los indicadores que se establecen en tiempo de ejecución. Así que termino con cadenas que se parecen a ate1\ratv0\rat+OSA=7\rat+OSX=255\r.

Me gustaría ver lo que he construido y lo que estoy presionando. No puedo hacer esto, porque std::cout lee el retorno de carro, actúa sobre él y desactiva la salida de mi consola.

EDIT: Aclaración, de nuevo: Quiero std::cout << "Writing: [" << str << "] to board." << std::endl; para producir (cuando str es ats203?\r):

Writing: [ats203?\r] to board. 
+3

Puede escapar el carácter de escape, por lo que '\\ R' dejará la cadena como un literal' "\ r" '. ..no estoy seguro si eso es lo que quieres o no. – prelic

+0

No entiendo, ¿por qué hay un '\ r' en su cadena en primer lugar? ¿Qué le gustaría mostrar en su lugar? –

+0

'\ r' es un carácter de retorno de carro - hará que el" cursor "salte al principio de la línea. Tal vez quería el carácter de nueva línea, '\ n'? – jrok

Respuesta

5
void Controller::write(const std::string& command_string) { 

    std::string display_string = std::regex_replace(command_string,std::regex("(\r)"),"\\r"); 

    std::cout << "Writing: [" << display_string << "] to board.\n"; 
    s.write(command_string); 

Entonces write("ats203?\r") literalmente imprimirá

ats203?\r 
1

No es exactamente 'mangling' los caracteres debido a una secuencia de escape. El '\ r' restablece el cursor, es decir, es un retorno de carro. Por lo tanto, el cursor va al principio y todo lo que se escribe ahora sobrescribe lo que hay en la línea.

Usted puede simplemente borrar cualquier instancia de \r en su cadena:

void Controller::write(const std::string& str) { 
    std::string str2(str); //Make a copy of the string as you are getting a const reference 
    char remove[] = "\r"; //Add any characters you wish to remove 

    for (unsigned int i = 0; i < sizeof(chars); ++i) { 
     str2.erase(std::remove(str2.begin(), str2.end(), chars[i]), str2.end()); 
    } 

    std::cout << "Writing: [" << str2 << "] to board." << std::endl; 
    s.write(str); 
} 

NOTA: remove es una función en <algorithm>, por lo que no se olvide de #include <algorithm>.

EDITAR: código para hacer una copia añadió, gracias a JROK por señalar que uno :)

+0

No puede hacer esto, 'str' es const. – jrok

+0

Oh ... No vi eso. Haré un cambio. –

+0

Si no hay una solución mejor, puedo quitar los caracteres ofensivos antes de mostrarlos; Sin embargo, esperaba que hubiera una manera en la que no tendría que hacer eso. – simont

1

Puede escribir una función para unescape esos caracteres.Ejemplo:

#include <string> 
#include <iostream> 

std::string unescape(const std::string& str){ 

    std::string res; 
    for(int i=0; i<str.length(); ++i){ 
     switch (str[i]){ 
      case '\r': 
       res+="\\r"; 
       break; 
      case '\n': 
       res+="\\n"; 
       break; 
      case '\\': 
       res+="\\\\"; 
       break; 
      case '\t': 
       res+="\\t"; 
       break; 
      //add other special characters if necessary... 
      default: 
       res += str[i]; 
     } 
    } 
    return res; 
} 

int main(){ 
    std::cout << unescape("hello\r\nworld\tsome\\words") << std::endl; 
} 

Salida:

hello\r\nworld\tsome\\words 
2

Aquí hay un bucle rápido para generar una cadena legible.

std::string str2; 
for (int i = 0; i < str.length(); ++i) 
{ 
    if (str[i] == '\r') 
    { 
     str2.push_back('\\'); 
     str2.push_back('r'); 
    } 
    else 
     str2.push_back(str[i]); 
} 
Cuestiones relacionadas