2010-09-22 13 views
78

Supongamos que tiene una cadena que NO es null terminada y conoce su tamaño exacto, entonces, ¿cómo puede imprimir esa cadena con printf en C? Recuerdo un procedimiento de este tipo, pero no puedo averiguar ahora ...Uso de printf con una cadena terminada no nula

+6

En 'C 'contexto, todas las cadenas están terminada en nulo. Las matrices de char sin nulo en ellas no son cadenas ... son matrices de char :) – pmg

+3

posible duplicado de [¿Cómo imprimo una cadena no terminada en nulo usando printf?] (Http://stackoverflow.com/ preguntas/2137779/how-do-i-print-a-non-null-terminated-string-using-printf) – Justin

+0

https://stackoverflow.com/questions/2239519/is-there-a-way-to-specify -how-many-characters-of-a-string-to-print-out-using-pri –

Respuesta

129

Hay una posibilidad con printf, que es la siguiente:

printf("%.*s", stringLength, pointerToString); 

No hay necesidad de copiar nada, no hay necesidad de modificar el original cadena o buffer

+9

Pero de todos modos es peligroso, alguien algún día imprimirá esta cadena con% s – pmod

+0

¡Sí, eso es todo! – whoi

+4

@Pmod: No necesariamente si el búfer no está expuesto al mundo exterior. También es muy útil simplemente imprimir * partes * de una cadena (que puede ser terminada nula, por supuesto). Si realmente quieres ver esto en acción, eche un vistazo al proxy SIP de OpenSER/Kamailio, donde evitan copiar cosas debido a esta técnica mucho (también usando sprintf). – DarkDust

1
#include<string.h> 
int main() 
{ 
/*suppose a string str which is not null terminated and n is its length*/ 
int i; 
for(i=0;i<n;i++) 
{ 
printf("%c",str[i]); 
} 
return 0; 
} 

he editado el código, aquí está otra manera:

#include<stdio.h> 
int main() 
{ 
printf ("%.5s","fahaduddin");/*if 5 is the number of bytes to be printed and fahaduddin is the string.*/ 

return 0; 

} 
+0

Muy mal rendimiento debido a muchas lecturas innecesarias de bytes (que vienen con una penalización de rendimiento) si el byte no está en una dirección alineada con palabras en la mayoría de las CPU) y también se realiza el análisis de formato y la aplicación para cada carácter. No hagas eso :-) Mira mi respuesta para la solución. – DarkDust

+0

Gracias por mencionar –

+0

@DarkDust: solo una máquina patológica penalizaría las lecturas de bytes no alineadas con los límites de las palabras. ¿Estás pensando en lecturas de palabras no alineadas con los límites de las palabras? ¿O alguna mierda de mips antiguos o algo así? –

5

printf("%.*s", length, string) no funcionará.

Esto significa imprimir hasta bytes de longitud O un byte nulo, lo que ocurra primero. Si su array-of-char no terminado en nulo contiene bytes nulos ANTES de la longitud, printf se detendrá en esos, y no continuará.

+13

¿cómo puede aparecer un nulo en una matriz de caracteres terminada no nula? Piénselo ... – pmg

+2

le funcionará porque sabe la longitud exacta – BlackBear

+4

¿Y cómo es esta una respuesta a la pregunta del OP? – Shahbaz

12

Puede usar un fwrite() para stdout!

fwrite(your_string, sizeof(char), number_of_chars, stdout); 

De esta manera se dará salida a los primeros caracteres (número definido en NUMBER_OF_CHARS variables) a un archivo, en este caso a la salida estándar (la salida estándar, la pantalla)!

+0

¡Muy útil cuando desea inspeccionar un buffer largo que contiene cadenas y ceros! – Elist

19

Aquí hay una explicación de cómo funciona %.*s, y dónde se especifica.

Las especificaciones de conversión en una cadena de plantilla printf tienen la forma general:

% [ param-no $] flags width [ . precision ] type conversion 

o

% [ param-no $] flags width . * [ param-no $] type conversion 

La segunda forma es para conseguir la precisión de la lista de argumentos:

También puede especificar una precisión de '*'. Esto significa que el siguiente argumento en la lista de argumentos (antes del valor real que se imprimirá) se usa como precisión. El valor debe ser un int, y se ignora si es negativo.

- Output conversion syntax en el manual de glibc

Para %s la cadena de formato, la precisión tiene un significado especial:

Una precisión se puede especificar para indicar el número máximo de caracteres para escribir; de lo contrario, los caracteres de la cadena hasta, pero sin incluir, el carácter nulo de terminación se escriben en la secuencia de salida.

- en el manual de glibc

Otras variantes útiles:

  • "%*.*s", maxlen, maxlen, val habrá justificar a la derecha, insertar espacios antes;
  • "%-*.*s", maxlen, maxlen, val justificará a la izquierda.
+0

Si entiendo correctamente, lo siguiente sería rellenar la salida aún así evitar un desbordamiento de cadena? '"% - *. * S ", relleno, str_view.size(), str_view.data()' – scx

1
printf("%.5s", pointerToNonNullTerminatedString); 

La longitud de la cadena será 5.

Cuestiones relacionadas