Trong C, một câu lệnh printf dài có thể được chia thành nhiều dòng không?


86

Tôi có tuyên bố sau:

printf("name: %s\targs: %s\tvalue %d\tarraysize %d\n", sp->name, sp->args, sp->value, sp->arraysize);

Tôi muốn chia tay nó. Tôi đã thử những cách sau đây nhưng nó không hoạt động.

printf("name: %s\t
args: %s\t
value %d\t
arraysize %d\n", 
sp->name, 
sp->args, 
sp->value, 
sp->arraysize);

Làm thế nào tôi có thể phá vỡ nó?


1
Một số gợi ý hay được đưa ra, nhưng không có gợi ý nào trong số chúng có thể rõ ràng hoặc có thể bảo trì được chỉ bằng bốn lệnh gọi printf () riêng biệt.
Clifford

@Clifford: sau đó bạn có thể viết C ++ để cout trông tốt hơn cho bạn.
Kiểm tra

Câu trả lời:


173

Nếu bạn muốn ngắt một chuỗi theo nghĩa đen thành nhiều dòng, bạn có thể nối nhiều chuỗi với nhau, mỗi chuỗi trên mỗi dòng, như sau:

printf("name: %s\t"
"args: %s\t"
"value %d\t"
"arraysize %d\n", 
sp->name, 
sp->args, 
sp->value, 
sp->arraysize);

85
chỉ nhận xét để giải thích sự thật C ít được biết đến rằng khoảng trắng giữa hai chuỗi là nối.
Brian Postow

2
@Lundin Có mỗi biến và giá trị của nó được trình bày rõ ràng trên dòng riêng của nó sẽ dễ đọc hơn nhiều đối với tôi. Bạn có thể tưởng tượng một trình gỡ lỗi trong IDE đặt tất cả các biến và giá trị vào một dòng không? Tôi không thể. (Vâng, tôi biết nó không đưa nhân vật mới-ranh giới giữa mỗi chuỗi, nhưng tôi đang so sánh readibility của mã nguồn tới readibility của các biến trong một debugger)
byxor

Việc nối này có được thực hiện bởi bộ tiền xử lý không?
debuti

21

Trình biên dịch C có thể dán các ký tự chuỗi liền kề thành một, như

printf("foo: %s "
       "bar: %d", foo, bar);

Bộ tiền xử lý có thể sử dụng dấu gạch chéo ngược làm ký tự cuối cùng của dòng, không tính CR (hoặc CR / LF, nếu bạn đến từ Windowsland):

printf("foo %s \
bar: %d", foo, bar);

6
Cái đầu tiên đã được đề xuất, cái thứ hai bị thực tế là nó bị vỡ nếu có bất kỳ khoảng trắng nào sau '\'; một lỗi có thể gây khó hiểu khi nó xảy ra.
Clifford

1
Cả hai ví dụ đó đều không liên quan gì đến bộ tiền xử lý C.
Dan Molding

@Dan cpp của tôi có vẻ hiểu / (xem chỉnh sửa của tôi ở trên). Tôi không chắc đây có phải là hành vi tiêu chuẩn hay không.
sigjuice

@Dan Trong khi việc nối các ký tự liền kề có thể được thực hiện với bộ tiền xử lý hoặc trình biên dịch (ở giai đoạn cuối trước khi biên dịch thực tế), việc xử lý tiếp nối dòng được thực hiện bởi bộ tiền xử lý, vì nếu không, macro nhiều dòng không thể thực hiện được. Cũng xem tại đây - gcc.gnu.org/onlineocs/cpp/Initial-processing.html
qrdl

2
@qrdl: Tệ thật, bạn nói đúng về cái thứ hai. Việc tiếp tục dòng luôn được thực hiện bởi bộ tiền xử lý. Đôi khi tôi cần được nhắc nhở rằng tôi không phải là người biết tất cả;) Tuy nhiên, tôi vẫn nghĩ rằng trong trường hợp bình thường, trình biên dịch kết hợp các chuỗi ký tự.
Dan Molding

20

Chỉ một số tùy chọn định dạng khác:

printf("name: %s\targs: %s\tvalue %d\tarraysize %d\n", 
        a,        b,        c,        d);

printf("name: %s\targs: %s\tvalue %d\tarraysize %d\n", 
              a,        b,        c,            d);

printf("name: %s\t"      "args: %s\t"      "value %d\t"      "arraysize %d\n", 
        very_long_name_a, very_long_name_b, very_long_name_c, very_long_name_d);

Bạn có thể thêm các biến thể về chủ đề. Ý tưởng ở đây là các trình phân tích printf()chuyển đổi và các biến tương ứng đều được xếp hàng "độc đáo" (đối với một số giá trị là "độc đáo").


Không có gì hoạt động ở đây, nhưng một ý tưởng mới lạ mà tôi chưa từng thấy trước đây. Tôi thích nó, bình luận tuyệt vời @pmg!
rpj

3

Cách thực tế tiêu chuẩn để phân chia các hàm phức tạp trong C là theo đối số:

printf("name: %s\targs: %s\tvalue %d\tarraysize %d\n", 
       sp->name, 
       sp->args, 
       sp->value, 
       sp->arraysize);

Hoặc nếu bạn sẽ:

const char format_str[] = "name: %s\targs: %s\tvalue %d\tarraysize %d\n";
...
printf(format_str, 
       sp->name, 
       sp->args, 
       sp->value, 
       sp->arraysize);

Bạn không nên chia nhỏ chuỗi, cũng không nên sử dụng \để ngắt dòng C. Mã như vậy nhanh chóng biến thành hoàn toàn không thể đọc được / không thể hiểu được.


3

Tôi không nghĩ rằng việc sử dụng một printfcâu lệnh để in các ký tự chuỗi như đã thấy ở trên là một cách lập trình tốt; thay vào đó, người ta có thể sử dụng đoạn mã dưới đây:

printf("name: %s\t",sp->name);
printf("args: %s\t",sp->args);
printf("value: %s\t",sp->value);
printf("arraysize: %s\t",sp->name); 
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.