2011-11-17 8 views
15

Tengo un búfer que recibo a través de un puerto serie. Cuando recibo un cierto caracter, sé que ha llegado una línea completa, y quiero imprimirlo con el método printf. Sin embargo, cada línea tiene un valor de longitud diferente, y cuando acabo de ir con:Printf un búfer de char que pasa la longitud en C

printf("%s", buffer); 

estoy imprimir la línea más caracteres adicionales pertenecientes a la antigua línea (si era más largo que el actual).

He leído here que es posible, al menos en C++, decir cuántos caracteres desea leer dado un %s, pero no tiene ejemplos y no sé cómo hacerlo en C. Cualquier ayuda ?

EDIT: Perfecto. Así que tengo tres soluciones: - impresión de carbón por carbón con un bucle for - usando el carácter de terminación - o el uso de *

pregunta es:. ¿Cuál es más rápido? Como estoy trabajando en un PIC de microchip y quiero que ocurra lo más rápido posible

+2

Cuando ha recibido de que * "cierto carácter" * y se estampan a 'buffer', anexar un carácter nulo ('\ 0') también. Esto "dice" 'sprintf()' cuándo dejar de imprimir caracteres. –

Respuesta

22

La cadena que tiene no tiene terminación nula, por lo tanto, printf (y cualquier otra función de cadena C) no puede determinar su longitud, por lo tanto continuará escribiendo los caracteres que encuentre allí hasta que tropiece con un carácter nulo que esté allí.

Para resolver su problema, puede:

  • uso fwrite sobre stdout:

    fwrite(buffer, buffer_length, 1, stdout); 
    

    Esto funciona porque fwrite no está pensado para imprimir sólo las cadenas, pero cualquier tipo de datos, por lo no busca un carácter nulo de terminación, pero acepta la longitud de los datos para escribir como un parámetro;

  • nulo interrumpir el búfer de forma manual antes de imprimir:

    buffer[buffer_length]=0; 
    printf("%s", buffer); /* or, slightly more efficient: fputs(buffer, stdout); */ 
    

    Esto podría ser una mejor idea si usted tiene que hacer cualquier otro procesamiento de cadenas sobre buffer, que ahora será terminada en nulo y así manejable funciones normales de procesamiento de cadenas en C

+0

Me sorprende que las respuestas a los duplicados de esta pregunta SO no incluyan este método, sino que solo sugieran 'for' loops ... – Alex

1

Una vez que haya identificado el final de la línea, debe añadir un carácter '\0' al final del búfer antes de enviarlo a printf.

+0

¿Alguien que ha votado negativamente quiere explicar por qué para poder mejorar mi respuesta? –

+0

Debe decir lo que hizo el PO incorrecto, además de cómo corregirlo. – Alex

37

Usted puede agregar un carácter nulo después de su carácter de terminación, y su printf va a trabajar, o se puede añadir un '.*' en su sentencia printf y proporcionar la longitud

printf("%.*s",len,buf); 

En C++ probablemente utilice el std :: string y el std :: cout lugar, como este:

std::cout << std::string(buf,len); 

Si lo que quieres es la velocidad más rápida y sin formato - a continuación, utilizar

fwrite(buf,1,len,stdout); 
+0

bueno, no sabía esto – Ben

+0

Perfecto. Así que tengo tres soluciones: imprimir char por char con un bucle for, usar el carácter de terminación o usar. * PREGUNTA ES: ¿cuál es más rápido? Porque estoy trabajando en un microchip PIC y quiero que ocurra rápido –

+0

@RomanRdgz: mis conjeturas: 'fwrite' o null-termintion +' fputs' debería ser el más rápido, seguido de null-termintion + 'printf' (podría ser más lento) porque puede que tenga que analizar la cadena de formato, a menos que el compilador sea muy inteligente) luego 'printf' con'. * '(seguramente necesita analizar la cadena de formato) y la última impresión char por char (probablemente la más lenta, debido a todas las llamadas de función, que sin embargo podrían estar en línea). –

3

Usted puede poner un NUL (0x0) en el tampón después de recibir el último carácter.

buffer[i] = 0;

Cuestiones relacionadas