Làm thế nào để định dạng chuỗi bằng printf () để có được độ dài bằng nhau trong đầu ra?


92

Tôi có hai chức năng, một chức năng tạo ra các thông báo như thế Starting initialization...và một chức năng khác kiểm tra mã trả về và kết quả đầu ra "Ok", "Warning"hoặc "Error". Tuy nhiên, đầu ra được tạo ra có độ dài khác nhau:

Starting initialization...Ok.
Checking init scripts...Ok.

Làm thế nào tôi có thể nhận được một cái gì đó như thế này:

Starting initialization...       Ok.
Checking init scripts...         Ok.

Câu trả lời:


159

Bạn có thể chỉ định chiều rộng trên các trường chuỗi, ví dụ:

printf("%-20s", "initialization...");

và sau đó bất cứ thứ gì được in với trường đó sẽ được đệm trống theo chiều rộng mà bạn chỉ định.

Bên -trái căn chỉnh văn bản của bạn trong trường đó.


130
Chao ôi, tôi không đủ khéo léo để đếm cao như vậy. Tuy nhiên, tôi tin tưởng vào Người hỏi phải đủ thông minh để suy luận từ ví dụ của tôi :)
Carl Smotricz

3
những gì về đúng hợp lý? Không có bất kỳ cờ nêu tại K & R
Ungeheuer

9
Đúng hợp lý là mặc định. Nếu không có một -, dữ liệu của bạn sẽ được căn chính xác trong một trường có chiều rộng bạn đã chỉ định.
Carl Smotricz

24

printfcho phép định dạng với các chỉ định chiều rộng. ví dụ


printf( "%-30s %s\n", "Starting initialization...", "Ok." );

Bạn sẽ sử dụng công cụ xác định độ rộng âm để chỉ ra căn trái vì mặc định là sử dụng căn phải.


18

Ngoài ra, nếu bạn muốn sự linh hoạt khi chọn width, bạn có thể chọn giữa một trong hai định dạng sau (có hoặc không cắt bớt):

int width = 30;
//no truncation uses %-*s
printf( "%-*s %s\n", width, "Starting initialization...", "Ok." );
// output is "Starting initialization...     Ok."

//truncated to the specified width uses %-.*s
printf( "%-.*s %s\n", width, "Starting initialization...", "Ok." ); 
// output is "Starting initialization... Ok."

13

Ngoài ra còn có công cụ %nsửa đổi có thể giúp ích trong một số trường hợp nhất định. Nó trả về cột mà chuỗi cho đến nay. Ví dụ: bạn muốn viết một số hàng có chiều rộng bằng chiều rộng của hàng đầu tiên như một bảng.

int width1, width2;
int values[6][2];
printf("|%s%n|%s%n|\n", header1, &width1, header2, &width2);

for(i=0; i<6; i++)
   printf("|%*d|%*d|\n", width1, values[i][0], width2, values[i][1]);

sẽ in ra 2 cột có cùng chiều rộng với bất kỳ chiều dài nào mà hai chuỗi header1header2có thể có. Tôi không biết nếu tất cả các triển khai đều có %nnhưng Solaris và Linux thì có.


Giải pháp này hoạt động, nhưng bất kỳ ai sử dụng nó và đưa nó vào mã của họ nên nhận thức được nguy cơ giới thiệu các lỗ hổng bộ nhớ .
Matthew Cole

0

Ngoài ra còn có một giải pháp công nghệ khá thấp là đếm thêm khoảng trắng bằng tay để làm cho các tin nhắn của bạn trở nên thẳng hàng. Không có gì ngăn cản bạn bao gồm một vài dấu cách ở cuối trong chuỗi thư của bạn.


-2

Bắt đầu với việc sử dụng Tab, công cụ sửa đổi ký tự \ t . Nó sẽ chuyển đến một vị trí cố định (cột, biệt ngữ đầu cuối). Tuy nhiên, sẽ không có ích gì nếu có sự khác biệt lớn hơn chiều rộng cột (4 ký tự, nếu tôi nhớ chính xác).

Để khắc phục điều đó, hãy viết nội dung "OK / NOK" của bạn bằng cách sử dụng số Tab cố định (5? 6 ?, hãy thử), sau đó quay lại ( \ r ) mà không có lớp lót mới và viết tin nhắn của bạn.


5
Luôn có nguy cơ một chuỗi dài hơn điểm dừng của tab, do đó buộc tab và văn bản kết quả được căn chỉnh sai.
PP.

Không hẳn ... trước tiên hãy viết cụm từ OK / NOK, sau đó là / r, bây giờ viết cụm từ, bây giờ là / n. Cụm từ có thể ghi đè OK / NOK. Nhưng cách của bạn là cách tốt hơn, tôi không biết về biện minh tiêu cực.
jpinto3912
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.