2009-01-16 11 views
8

A partir de ahora estoy usando la siguiente línea para imprimir con punto de salida¿Cómo imprimir un guion o punto usando fprintf/printf?

fprintf(stdout, "%-40s[%d]", tag, data); 

estoy esperando la salida sería algo así como después,

 
Number of cards..................................[500] 
Fixed prize amount [in whole dollars]............[10] 
Is this a high winner prize?.....................[yes] 

Cómo imprimir guión o punto usando fprintf/printf?

Respuesta

10

Un enfoque más rápido:

Si la cantidad máxima de relleno que que jamás la necesidad se conoce de antemano (que normalmente es el caso cuando está formateando una tabla de ancho fijo como la que tiene), puede usar una cadena de "relleno" estático y simplemente tomar una porción de ella. Esto será más rápido que llamar printf o cout en un bucle.

static const char padder[] = "......................"; // Many chars 

size_t title_len = strlen(title); 
size_t pad_amount = sizeof(padder) - 1 - title_len; 

printf(title); // Output title 

if (pad_amount > 0) { 
    printf(padder + title_len); // Chop! 
} 

printf("[%d]", data); 

Incluso podría hacerlo en un comunicado, con algún acto de fe:

printf("%s%s[%d]", title, padder + strlen(title), data); 
+0

su última sugerencia se rompe si 'strlen (título)> strlen (padder)' – Christoph

+0

@Christoph, de ahí el proclamado "salto de fe" :) –

+0

@Ates: concepto interesante, esta 'programación fiel' de usted;) – Christoph

2

Tendrá que salir la cuerda con el relleno de punto o guión usted mismo.

Algo así como (perdona mi C, que es oxidado):

printAmount(char *txt, int amt) { 
    printf("%s",txt); 
    for(int xa=strlen(txt); xa<40; xa++) { putc('.'); } 
    printf("[%d]",amt); 
    printf("\n"); 
    } 
3

Usted no puede hacerlo en un comunicado. Puede utilizar sprintf, a continuación, sustituir puntos para espacios mismo, o hacer algo como

int chars_so_far; 
char padder[40+1]= '..........'; //assume this is 40 dots. 
printf("%.40s%n",tag,&chars_so_far); 
printf("%s[%d]",padder+chars_so_far,data); 

Editar: simplificado mi ejemplo anterior basado en el concepto foulard @Ates'. De esta forma no se requieren 'saltos de fe', sobre si la cadena de etiquetas es demasiado grande o demasiado pequeña: siempre comienza los datos en la columna 41.

+0

Creo que se puede hacer en una sola declaración. –

+0

@Ates: podría, pero no sin dos llamadas a 'strlen()' si desea verificar correctamente los límites, ¡por lo tanto, debe almacenar en caché este valor -> dos instrucciones! – Christoph

1

Sugiero escribir una función que adhiera una cadena con X caracteres y utilízalo para generar el primer argumento en tu cadena printf. Algo así como:

char s[40]; 
pad_str(tag, s, 40, '.'); 
fprintf(stdout, "%-40s[%d]", s, data); 

Tenga en cuenta que la tercera línea de datos de la muestra tendría este formato:

"%-40s[%s]" 
2

Otra solución utilizando una función auxiliar pequeño

static inline size_t min(size_t a, size_t b) 
{ 
    return a < b ? a : b; 
} 

A continuación, puede hacer lo siguiente :

char padder[] = "........................................"; 
int len = min(strlen(tag), sizeof(padder) - 1); 
printf("%.*s%s[%d]", len, tag, padder + len, data); 

Esto es esencialmente lo publicado Ates, pero en realidad me cuenta de esto por mi cuenta;)

+0

Cambie size_t por int; debe pasar un int al '*' en la familia de funciones printf(). –

+0

O haga que el ayudante sea más útil: printf ("% s% s [% d]", título, getPadding (título), datos); –

+0

@Jonathan: gracias, lo corrigió ... – Christoph

9

Usted puede hacer esto con iostreams en lugar de printf

cout << setw(40) << setfill('.') << left << tag[i] << '[' << data[i] << ']' << endl; 

O si realmente necesita utilizar fprintf (por ejemplo, le pasaron un ARCHIVO * para escribir a)

strstream str; 
str << setw(40) << setfill('.') << left << tag[i] << '[' << data[i] << ']' << endl; 
printf(%s", str.str()); 
+0

+1 por ser fácil de leer y comprender, y por no romperse en ciertas situaciones (aunque poco comunes). –

0

Creo que hay una manera mejor.

#include <string.h> 
#include <stdio.h> 

#define MIN(A,B) ((A)<(B)?(A):(B)) 
char *dashpad(char *buf, int len, const char *instr) { 
    memset(buf, '-', len); 
    buf[len] = 0; 
    int inlen = strlen(instr); 
    memcpy(buf, instr, MIN(len, inlen)); 
    return buf; 
} 
main() { 
    char buf[40]; 
    printf("%s\n", dashpad(buf, 40, "Hello world, dash padded ")); 
} 
+0

Primero llenar toda la memoria intermedia con el carácter de la almohadilla, y luego sobreescribirlos parece un poco derrochador ... –

+0

Además, tienes un desbordamiento del búfer (no te encanta C) - s/be: buf [len-1 ] = 0; –

+0

Y tiene un error de borrado nulo en min(), que también debería ser len-1. –

Cuestiones relacionadas