No saber el recuento en tiempo de compilación no es un obstáculo para escribir un bucle.
Keith Thompson
Tu pregunta es razonablemente clara (y la respuesta real es que no existe un printfformato que haga lo que quieres), pero tus comentarios me dejan inseguro de lo que estás preguntando. Hablas de una cadena de formato y argumentos que se pasan a tu función. ¿Sobre qué función estás preguntando? Parece que hay cosas que no nos estás diciendo.
Keith Thompson
@KeithThompson Escribí un envoltorio sobre 'printf', por lo que esos argumentos eran los mismos que para el original, perdón por la confusión. Y debería haber descrito mejor la razón por la que necesitaba esto, tienes razón.
Muis
Me temo que todavía no tengo una idea clara de lo que está tratando de hacer o (sin ofender a @synthesizerpatel) por qué aceptó la respuesta que hizo, que no pretendía ser una solución seria.
Keith Thompson
Respuestas:
63
Respuesta corta: sí, respuesta larga: no como la quieres.
Puede utilizar la forma% * de printf , que acepta un ancho variable. Y, si usa '0' como su valor para imprimir, combinado con el texto alineado a la derecha que tiene un relleno de cero a la izquierda ...
printf("%0*d\n", 20, 0);
produce:
00000000000000000000
Con mi lengua firmemente plantada en mi mejilla, ofrezco este pequeño fragmento de código de un espectáculo de terror.
Algunas veces solo tienes que hacer las cosas mal para recordar por qué te esfuerzas tanto el resto del tiempo.
No recuerdo claramente lo que estaba pensando, pero en su código el límite superior es 4096. Supongo que podrías hacer mallocel amortiguador.
Keith Thompson
2
Lo suficientemente justo. ¡Lucha a cuchillo == evitada!
synthesizerpatel
4
Este estilo es mejor que asignar caracteres directamente en un bucle.
liuyang1
2
Sí. Este método es terrible, pero responde a la pregunta de los OP.
synthesizerpatel
2
¿Puede aclarar qué quiere decir con espectáculo de terror? Siento que está tratando de advertir sobre algo, pero no estoy seguro de qué ... ¿solo está tratando de señalar el peligro de desbordamiento cuando usa "% *"?
Cheshirekow
117
Puede utilizar la siguiente técnica:
printf("%.*s", 5, "=================");
Esto imprimirá "====="
Me funciona en Visual Studio, no hay razón para que no funcione en todos los compiladores de C.
Es lamentable que esta respuesta no tenga una calificación más alta considerando que no solo es correcta sino que funciona en varias plataformas. Probado en OSX, Linux y OpenBSD en C, así como Perl (que está terminando la anywho C printf)
synthesizerpatel
3
Gracias, recordé haber hecho esto hace 10 años, pero lo olvidé y luego lo redescubrí.
rep_movsd
19
Aunque no es exactamente flexible. Si el ancho es mayor que la cadena en sí, no imprimirá más que la cadena (al menos no en mi simple experimento con gcc).
Mats Petersson
1
Esto funciona mejor que la respuesta de Synthesizerpatel. Cuando probé el espacio en lugar de un cero y el ancho es cero, todavía se imprime un solo espacio. Este no lo hace.
negro
1
¡Buena atrapada! @rep_movsd
Juan Diego Godoy Robles
24
Si se limita a repetir un 0 o un espacio, puede hacer:
No existe tal cosa. Tendrá que escribir un bucle usando printfo puts, o escribir una función que copie los tiempos de recuento de cadenas en una nueva cadena.
Es muy extraño que pueda tener las expresiones más complicadas, pero algo tan simple como repetir un carácter no es compatible.
Muis
¿Por qué? Puede hacerlo simplemente agregando un bucle alrededor de lo que desea repetir. La mayor parte de lo que hace printf son cosas que no podrías hacer en tu propio código [muy fácilmente]. Dejemos que las bibliotecas hagan la parte difícil y que el programa de aplicación haga las partes fáciles, creo que ese es el tema aquí.
Mats Petersson
5
Y si le parece bien, supongo que el comité de estándares de C está interesado en sugerencias de mejoras, y una implementación de muestra dentro de glibc tal vez mejoraría las posibilidades de que alguna vez se convierta en estándar. Si lo implementa, tal vez alguien más piense que es una buena idea. Solo ha estado ausente durante los últimos 50 años desde que se introdujo por primera vez printf, por lo que quizás sea solo un descuido ...;)
Mats Petersson
@MatsPetersson Eso no es una solución, porque no conozco la cadena de formato de antemano, vea mi respuesta a Mokammel.
Muis
3
¿Por qué se rechaza esto? Si está rechazando esta respuesta, hágame saber con qué no está satisfecho ...
Mats Petersson
6
printfno hace eso, y printfes excesivo para imprimir un solo carácter.
char c = '*';
int count = 42;
for (i = 0; i < count; i ++) {
putchar(c);
}
No se preocupe si esto es ineficaz; putchar()almacena en búfer su salida, por lo que no realizará una operación de salida física para cada carácter a menos que sea necesario.
No sé la cadena de formato o los argumentos que se pasarán a mi función, podrían leerse desde un archivo xml o ser la entrada del usuario.
Muis
Tienes el carácter y la cantidad de veces que necesitas imprimirlo, ¿verdad? ¿Qué más información necesitas? Para imprimir un solo carácter printf, la cadena de formato es "%c". Pero no necesita usar printf, y en ese caso no necesita una cadena de formato en absoluto. (Simplemente no hay una printfcadena de formato que imprima un carácter varias veces, pero hay otras y mejores formas de realizar la tarea).
Keith Thompson
Como dije, no sé qué representan los argumentos de mi función. Supongamos que leo la cadena de formato y los argumentos de un archivo XML y los paso a printf (), ¿cómo podría mi función saber que necesita un bucle y que el segundo argumento representa un recuento? Eso es lo que quiero decir con que mi entrada no se conoce en tiempo de compilación.
Muis
4
@Joshua: ¿Los argumentos para qué función? Tu pregunta ni siquiera menciona una función.
Keith Thompson
1
@Joshua está realmente confundido, lo cual es evidente por su uso excesivo del tiempo de compilación y la función 'va a saber'. Realmente no es tan difícil como lo que está haciendo parecer. Necesita una función para imprimir un carácter 'x' n veces. Si proviene de xml, analice el xml y averigüe el carácter a imprimir y cuántas veces necesita imprimir. Use strlen para obtener la longitud de la cadena en los lugares donde su campo de cadena xml decide cuántas veces se debe imprimir el carácter 'x'.
SayeedHussain
6
Si tiene un compilador que admita la función alloca (), entonces esta es una posible solución (aunque bastante fea):
Sugeriría en putchar('x')lugar de printf("%c", 'x').
Paddu
¿Por qué? ¿El tiempo de ejecución es menor?
71GA
4
#include<stdio.h>#include<string.h>voidrepeat_char(unsignedint cnt, char ch){
char buffer[cnt + 1];
/*assuming you want to repeat the c character 30 times*/memset(buffer,ch,cnd); buffer[cnt]='\0';
printf("%s",buffer)
}
char buffer[41];
memset(buffer, '-', 40); // initialize all with the '-' character<br /><br />
buffer[40] = 0; // put a NULL at the end<br />printf("%s\n", buffer); // show 40 dashes<br />
printf
formato que haga lo que quieres), pero tus comentarios me dejan inseguro de lo que estás preguntando. Hablas de una cadena de formato y argumentos que se pasan a tu función. ¿Sobre qué función estás preguntando? Parece que hay cosas que no nos estás diciendo.Respuestas:
Respuesta corta: sí, respuesta larga: no como la quieres.
Puede utilizar la forma% * de printf , que acepta un ancho variable. Y, si usa '0' como su valor para imprimir, combinado con el texto alineado a la derecha que tiene un relleno de cero a la izquierda ...
printf("%0*d\n", 20, 0);
produce:
00000000000000000000
Con mi lengua firmemente plantada en mi mejilla, ofrezco este pequeño fragmento de código de un espectáculo de terror.
Algunas veces solo tienes que hacer las cosas mal para recordar por qué te esfuerzas tanto el resto del tiempo.
#include <stdio.h> int width = 20; char buf[4096]; void subst(char *s, char from, char to) { while (*s == from) *s++ = to; } int main() { sprintf(buf, "%0*d", width, 0); subst(buf, '0', '-'); printf("%s\n", buf); return 0; }
fuente
4096
. Supongo que podrías hacermalloc
el amortiguador.Puede utilizar la siguiente técnica:
printf("%.*s", 5, "=================");
Esto imprimirá
"====="
Me funciona en Visual Studio, no hay razón para que no funcione en todos los compiladores de C.fuente
Si se limita a repetir un 0 o un espacio, puede hacer:
Para espacios:
printf("%*s", count, "");
Para ceros:
printf("%0*d", count, 0);
fuente
En c ++ puede usar std :: string para obtener un carácter repetido
printf("%s",std::string(count,char).c_str());
Por ejemplo:
printf("%s",std::string(5,'a').c_str());
salida:
fuente
No existe tal cosa. Tendrá que escribir un bucle usando
printf
oputs
, o escribir una función que copie los tiempos de recuento de cadenas en una nueva cadena.fuente
printf
no hace eso, yprintf
es excesivo para imprimir un solo carácter.char c = '*'; int count = 42; for (i = 0; i < count; i ++) { putchar(c); }
No se preocupe si esto es ineficaz;
putchar()
almacena en búfer su salida, por lo que no realizará una operación de salida física para cada carácter a menos que sea necesario.fuente
printf
, la cadena de formato es"%c"
. Pero no necesita usarprintf
, y en ese caso no necesita una cadena de formato en absoluto. (Simplemente no hay unaprintf
cadena de formato que imprima un carácter varias veces, pero hay otras y mejores formas de realizar la tarea).Si tiene un compilador que admita la función alloca (), entonces esta es una posible solución (aunque bastante fea):
printf("%s", (char*)memset(memset(alloca(10), '\0', 10), 'x', 9));
Básicamente, asigna 10 bytes en la pila que se rellenan con '\ 0' y luego los primeros 9 bytes se rellenan con 'x'.
Si tiene un compilador C99, esta podría ser una solución más ordenada:
for (int i = 0; i < 10; i++, printf("%c", 'x'));
fuente
putchar('x')
lugar deprintf("%c", 'x')
.#include <stdio.h> #include <string.h> void repeat_char(unsigned int cnt, char ch) { char buffer[cnt + 1]; /*assuming you want to repeat the c character 30 times*/ memset(buffer,ch,cnd); buffer[cnt]='\0'; printf("%s",buffer) }
fuente
puedes crear una función que haga este trabajo y usarla
#include <stdio.h> void repeat (char input , int count ) { for (int i=0; i != count; i++ ) { printf("%c", input); } } int main() { repeat ('#', 5); return 0; }
Esto saldrá
fuente
i < count
. De lo contrario, una entrada negativa para el recuento podría dar como resultado muchas impresiones no deseadas.printf("%.*s\n",n,(char *) memset(buffer,c,n));
n
<=sizeof(buffer)
[quizás también n <2 ^ 16]Sin embargo, el optimizador puede cambiarlo a
puts(buffer)
y luego la falta de EoS .....Y la suposición es que memset es una instrucción de ensamblador (pero sigue siendo un bucle en el chip).
Estrictamente visto, no hay solución dada la condición previa 'Sin bucle'.
fuente
char buffer[41]; memset(buffer, '-', 40); // initialize all with the '-' character<br /><br /> buffer[40] = 0; // put a NULL at the end<br /> printf("%s\n", buffer); // show 40 dashes<br />
fuente
Creo que haciendo algo como esto.
void printchar(char c, int n){ int i; for(i=0;i<n;i++) print("%c",c); } printchar("*",10);
fuente