ฉันได้รับข้อมูลโค้ดซึ่งมีไฟล์
printf("%.*s\n")
สิ่งที่ไม่%.*s
หมายถึง?
คำตอบ:
คุณสามารถใช้เครื่องหมายดอกจัน ( *
) เพื่อส่งผ่านตัวระบุความกว้าง / ความแม่นยำไปยังprintf()
แทนที่จะเข้ารหัสแบบยากลงในสตริงรูปแบบเช่น
void f(const char *str, int str_len)
{
printf("%.*s\n", str_len, str);
}
str_len
อาร์กิวเมนต์ต้องมีประเภทint
(หรือประเภทอินทิกรัลที่แคบกว่าซึ่งจะเลื่อนระดับเป็นint
) มันจะเป็นข้อผิดพลาดในการส่งผ่านlong
, size_t
ฯลฯ
%s
คือการพิมพ์สตริงย่อยของสตริงต้นฉบับ ในกรณีการใช้งานนี้str
จะชี้ไปที่จุดใดจุดหนึ่งภายในสตริงเดิม (อาจอยู่ที่จุดเริ่มต้น) และstr_len
จะระบุความยาวของสตริงย่อยที่ควรพิมพ์
ค่าจำนวนเต็มหรือ
*
ระบุความกว้างของฟิลด์ขั้นต่ำ ผลลัพธ์จะถูกเพิ่มด้วยอักขระเว้นวรรค (โดยค่าเริ่มต้น) หากจำเป็นทางด้านซ้ายเมื่อจัดชิดขวาหรือทางด้านขวาหากจัดชิดซ้าย ในกรณีที่ใช้ * ความกว้างจะถูกระบุโดยอาร์กิวเมนต์เพิ่มเติมประเภท int หากค่าของอาร์กิวเมนต์เป็นค่าลบจะส่งผลด้วย - แฟล็กที่ระบุและความกว้างของฟิลด์บวก (หมายเหตุ: นี่คือความกว้างขั้นต่ำ: ค่านี้จะไม่ถูกตัดทอน)
.
ตามด้วยเลขจำนวนเต็มหรือ * หรือไม่ระบุความแม่นยำของการแปลง ในกรณีที่ใช้ * ความแม่นยำจะถูกระบุโดยอาร์กิวเมนต์เพิ่มเติมประเภท int หากค่าของอาร์กิวเมนต์นี้เป็นลบจะถูกละเว้น หากไม่มีการใช้ตัวเลขหรือ * ความแม่นยำจะถือเป็นศูนย์ ดูตารางด้านล่างสำหรับผลกระทบที่แน่นอนของความแม่นยำ
ดังนั้นถ้าเราลองทั้งข้อกำหนดการแปลง
#include <stdio.h>
int main() {
int precision = 8;
int biggerPrecision = 16;
const char *greetings = "Hello world";
printf("|%.8s|\n", greetings);
printf("|%.*s|\n", precision , greetings);
printf("|%16s|\n", greetings);
printf("|%*s|\n", biggerPrecision , greetings);
return 0;
}
เราได้ผลลัพธ์:
|Hello wo|
|Hello wo|
| Hello world|
| Hello world|
ฉันไม่คิดว่ารหัสด้านบนถูกต้อง แต่ (ตามคำอธิบายนี้printf()
) .*
หมายถึง
ความกว้างไม่ได้ระบุไว้ในสตริงรูปแบบ แต่เป็นอาร์กิวเมนต์ค่าจำนวนเต็มเพิ่มเติมที่นำหน้าอาร์กิวเมนต์ที่ต้องจัดรูปแบบ '
ดังนั้นจึงเป็นสตริงที่มีความกว้างที่ผ่านได้เป็นอาร์กิวเมนต์
int
(หรือส่วนหนึ่งของมัน) - ไม่เพียงใดค่าหนึ่งเช่นง่ายขึ้นหรือนามแฝงที่เป็นไปได้เช่นsize_t
std::string::size_type
สิ่งนี้ยิ่งทำให้สับสนมากขึ้นโดยพิจารณาว่าหน้าที่อ้างอิงกล่าวถึงsize_t
เป็นหนึ่งในตัวระบุประเภทที่รองรับ
ดู: http://www.cplusplus.com/reference/clibrary/cstdio/printf/
.*
ความแม่นยำไม่ได้ระบุไว้ในสตริงรูปแบบ แต่เป็นอาร์กิวเมนต์ค่าจำนวนเต็มเพิ่มเติมที่นำหน้าอาร์กิวเมนต์ที่ต้องจัดรูปแบบ
s
สตริงอักขระ
printf
โทรที่ถูกต้อง