2009-01-16 34 views
8

Tính đến bây giờ tôi đang sử dụng bên dưới dòng in với của dot raLàm cách nào để in dấu gạch ngang hoặc dấu chấm bằng fprintf/printf?

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

tôi hy vọng sản lượng sẽ là một cái gì đó như sau,

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

Làm thế nào để in ra dấu gạch ngang hay dấu chấm sử dụng fprintf/printf?

Trả lời

10

Một cách tiếp cận nhanh hơn:

Nếu số tiền tối đa của padding rằng bạn sẽ không bao giờ nhu cầu được biết trước (thường là trường hợp khi bạn định dạng bảng có chiều rộng cố định như bảng bạn có), bạn có thể sử dụng chuỗi "padder" tĩnh và chỉ cần lấy một đoạn ra khỏi nó. Thao tác này sẽ nhanh hơn gọi số printf hoặc cout trong vòng lặp.

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

Bạn thậm chí có thể làm điều đó trong một tuyên bố, với một số bước nhảy vọt của đức tin:

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

đề nghị cuối cùng của bạn vi phạm nếu 'strlen (title)> strlen (padder)' – Christoph

+0

@Christoph, do đó tuyên bố "bước nhảy vọt của đức tin" :) –

+0

@Ates: khái niệm thú vị, 'lập trình trung thành' này của bạn;) – Christoph

2

Bạn sẽ phải tự tạo chuỗi bằng dấu chấm hoặc dấu gạch ngang.

Giống như (tha thứ cho C của tôi, đó là gỉ):

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

Bạn không thể làm điều đó trong một tuyên bố. Bạn có thể sử dụng sprintf, sau đó thay thế dấu chấm cho các không gian chính mình, hoặc làm cái gì đó như

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

Edit: Giản ví dụ của tôi ở trên dựa trên khái niệm padder @Ates'. Bằng cách này không yêu cầu bất kỳ 'bước nhảy đức tin nào', về việc chuỗi thẻ quá lớn hay quá nhỏ - nó luôn bắt đầu dữ liệu trong cột 41.

+0

Tôi nghĩ rằng nó có thể được thực hiện trong một tuyên bố. –

+0

@Ates: nó có thể, nhưng imo không có hai cuộc gọi đến 'strlen()' nếu bạn muốn kiểm tra đúng ranh giới - do đó, bạn cần phải nhớ giá trị này -> hai câu lệnh! – Christoph

1

Tôi khuyên bạn nên viết một hàm có chứa chuỗi Ký tự X và sử dụng ký tự đó để tạo đối số đầu tiên cho chuỗi printf của bạn. Một cái gì đó như:

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

Lưu ý rằng dòng thứ ba của dữ liệu mẫu của bạn sẽ cần phải định dạng này:

"%-40s[%s]" 
2

Một giải pháp sử dụng một hàm helper nhỏ

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

Sau đó, bạn có thể làm như sau :

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

Đây thực chất là gì Ates được đăng, nhưng tôi thực sự figured này ra một mình;)

+0

Thay đổi size_t thành int; bạn phải chuyển một int vào '*' trong họ printf() của các hàm. –

+0

Hoặc làm cho trình trợ giúp hữu ích hơn: printf ("% s% s [% d]", tiêu đề, getPadding (tiêu đề), dữ liệu); –

+0

@ Jonathan: cảm ơn, sửa chữa nó ... – Christoph

9

Bạn có thể dễ dàng làm điều này với iostreams thay vì printf

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

Hoặc nếu bạn thực sự cần phải sử dụng fprintf (nói, bạn được chuyển một TẬP_TIN * để ghi vào)

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

+1 để dễ đọc và dễ hiểu và không bị phá vỡ dưới một số trường hợp (mặc dù có phần không phổ biến). –

0

Tôi nghĩ có cách tốt hơn.

#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

Đầu tiên điền vào toàn bộ bộ đệm với ký tự pad, và sau đó ghi đè lên chúng có vẻ hơi lãng phí ... –

+0

Ngoài ra, bạn có một bộ đệm tràn ngập (không bạn yêu C) - s/be: buf [len-1 ] = 0; –

+0

Và bạn có một lỗi vô hiệu trong bạn min(), cũng nên được len-1. –

Các vấn đề liên quan