Usando printf con una cadena terminada no nula

4 minutos de lectura

avatar de usuario
quien yo

Supongamos que tiene una cadena que NO es null terminado y sabe su tamaño exacto, entonces, ¿cómo puede imprimir esa cadena con printf ¿C ª? Recuerdo tal método pero no puedo averiguarlo ahora…

  • En C contexto, todas las cadenas terminan en nulo. Las matrices de char sin un valor nulo en ellas no son cadenas… son matrices de char 🙂

    – pmg

    22 de septiembre de 2010 a las 9:30

  • posible duplicado de ¿Cómo imprimo una cadena no terminada en nulo usando printf?

    – Justin

    8 de noviembre de 2011 a las 9:49

  • stackoverflow.com/questions/2239519/…

    – Ciro Santilli Путлер Капут 六四事

    30 de julio de 2017 a las 9:57

  • ¿Quiere imprimir “Mi cadena\0\0\0\0caracteres aleatorios”?

    – Sandburg

    4 de marzo a las 8:30

Hay una posibilidad con printf, es así:

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

No es necesario copiar nada, no es necesario modificar la cadena o el búfer original.

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

    – pmod

    22 de septiembre de 2010 a las 7:57

  • @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 terminar en nulo, por supuesto). Si realmente quiere ver esto en acción, eche un vistazo al proxy SIP de OpenSER/Kamailio, donde evitan copiar muchas cosas debido a esta técnica (también usando sprintf).

    – Polvo oscuro

    22 de septiembre de 2010 a las 8:53

  • No tengo nada en contra de imprimir una parte de una cadena terminada en NULL de la manera que describiste. También lo hago de esa manera en mis progs. Pero estoy en contra de usar cadenas terminadas en NON-NULL para fingir que están terminadas. Alguien puede algún día str (n) copiarlo o exponerlo afuera sin darse cuenta de esto específico.

    – pmod

    22 de septiembre de 2010 a las 10:16

  • Para mí, es muy útil cuando recibo una cadena terminada en un valor no nulo de una API (¡algunas API de Windows hacen esto!) y tengo que devolverla de una manera ‘razonable’. Entonces: ¡larga vida a %.*s (o %.*S que también hará la conversión UNICODE <-> SINGLE-BYTE para usted! 😉 )

    – FrizzTheSnail

    12 de julio de 2013 a las 15:46

  • @user1424739: En tu caso printf imprimirá hasta 11 caracteres o hasta que encuentre NULL, lo que ocurra primero; en su ejemplo NULL viene primero. Especificar una longitud máxima no hace que NULL pierda su significado de “fin de cadena” para printf.

    – Polvo oscuro

    17 de febrero de 2019 a las 8:59

avatar de usuario
tobu

Aquí hay una explicación de cómo %.*s funciona 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 obtener 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 va a imprimir) se usa como precisión. El valor debe ser un entero y se ignora si es negativo.

Sintaxis de conversión de salida en el manual de glibc

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

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

Otras conversiones de salida en el manual de glibc

Otras variantes útiles:

  • "%*.*s", maxlen, maxlen, val justificará a la derecha, insertando espacios antes;
  • "%-*.*s", maxlen, maxlen, val justificará a la izquierda.

  • Si entiendo correctamente, lo siguiente rellenaría la salida y aún así evitaría un desbordamiento de cadena. "%-*.*s", padding, str_view.size(), str_view.data()

    – scx

    25 de febrero de 2018 a las 1:01

¡Puede usar un fwrite() para la salida estándar!

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

De esta manera, generará los primeros caracteres (el número definido en la variable number_of_chars) en un archivo, en este caso en stdout (la salida estándar, su pantalla).

  • ¡Muy útil cuando desea inspeccionar un búfer largo que contiene cadenas y ceros!

    – Elista

    11 de septiembre de 2016 a las 12:17

  • Esta es la única forma de imprimir una cadena que contenga \0. ¡Gracias!

    –Mark McDonald

    13 de noviembre de 2020 a las 5:02

  • Por ahora (y tal vez así sucesivamente), sizeof(char) siempre es 1

    – Faran Aiki

    3 oct 2021 a las 14:14

avatar de usuario
Todd liberado

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

Esto significa imprimir HASTA bytes de longitud O un byte nulo, lo que ocurra primero. Si su matriz de caracteres no terminada en nulo contiene bytes nulos ANTES de la longitud, printf se detendrá en ellos y no continuará.

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

La longitud de la cadena será de 5.

#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;
}

Edité el código, aquí hay otra forma:

#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;

}

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad