เหตุใดจึงต้องใช้การขึ้นบรรทัดใหม่แทนที่จะนำหน้าด้วย printf


79

printfผมได้ยินมาว่าคุณควรหลีกเลี่ยงการขึ้นบรรทัดใหม่ชั้นนำเมื่อใช้ ดังนั้นแทนที่จะprintf("\nHello World!")ใช้printf("Hello World!\n")

ในตัวอย่างข้างต้นนี้ไม่สมเหตุสมผลเนื่องจากเอาต์พุตจะแตกต่างกัน แต่ให้พิจารณาสิ่งนี้:

printf("Initializing");
init();
printf("\nProcessing");
process_data();
printf("\nExiting");

เปรียบเทียบกับ:

printf("Initializing\n");
init();
printf("Processing\n");
process_data();
printf("Exiting");

ฉันไม่เห็นประโยชน์ใด ๆ จากการขึ้นบรรทัดใหม่ยกเว้นว่าจะดูดีขึ้น มีเหตุผลอื่นอีกไหม?

แก้ไข:

ฉันจะอยู่คะแนนปิดที่นี่และตอนนี้ ฉันไม่คิดว่านี่เป็นของล้นล้นเพราะคำถามนี้ส่วนใหญ่เกี่ยวกับการออกแบบ ฉันก็จะบอกว่าถึงแม้มันอาจเป็นความคิดเห็นต่อเรื่องนี้คำตอบของ Kilian Fothและคำตอบของอาจารย์ก็พิสูจน์ให้เห็นว่ามีประโยชน์อย่างแท้จริงกับวิธีการหนึ่ง


5
คำถามนี้อยู่ที่ขอบระหว่าง "ปัญหาเกี่ยวกับรหัส" (ซึ่งอยู่นอกหัวข้อ) และ "การออกแบบซอฟต์แวร์แนวความคิด" (ซึ่งอยู่ในหัวข้อ) มันอาจถูกปิด แต่ไม่ได้ใช้มันแรงเกินไป ฉันคิดว่าการเพิ่มตัวอย่างรหัสที่เป็นรูปธรรมเป็นทางเลือกที่เหมาะสม
Kilian Foth

46
บรรทัดสุดท้ายจะรวมเข้ากับพรอมต์คำสั่งบน linux โดยไม่ต้องขึ้นบรรทัดใหม่
GrandmasterB

4
หาก "ดูดีขึ้น" และไม่มีข้อเสียนั่นเป็นเหตุผลที่ดีพอที่จะทำเช่นนั้น IMO เขียนโค้ดที่ดีก็ไม่ต่างกับการเขียนนวนิยายเรื่องที่ดีหรือกระดาษด้านเทคนิคที่ดี - มารอยู่เสมอในรายละเอียด
alephzero

5
ทำinit()และprocess_data()พิมพ์อะไรเอง คุณคาดหวังว่าผลลัพธ์จะเป็นอย่างไรหากพวกเขาทำ
Bergi

9
\nเป็นสายเทอร์มิ , ไม่ได้เป็นเส้นคั่น สิ่งนี้พิสูจน์ได้จากความจริงที่ว่าไฟล์ข้อความบน UNIX นั้นเกือบจะลงท้าย\nด้วย
Jonathon Reinhart

คำตอบ:


222

จำนวนเงินที่ยุติธรรมของเทอร์มินัล I / O เป็นแบบline-bufferedดังนั้นเมื่อสิ้นสุดข้อความด้วย \ n คุณสามารถมั่นใจได้ว่ามันจะถูกแสดงในเวลาที่เหมาะสม ด้วยการนำหน้า \ n ข้อความอาจแสดงหรือไม่แสดงพร้อมกัน บ่อยครั้งซึ่งหมายความว่าแต่ละขั้นตอนจะแสดงข้อความความคืบหน้าของขั้นตอนก่อนหน้าซึ่งทำให้ไม่เกิดความสับสนและสิ้นเปลืองเวลาเมื่อคุณพยายามเข้าใจพฤติกรรมของโปรแกรม


20
สิ่งนี้มีความสำคัญอย่างยิ่งเมื่อใช้ printf สำหรับการดีบักโปรแกรมที่ขัดข้อง การขึ้นบรรทัดใหม่ที่ส่วนท้ายของ printf หมายความว่า stdout ไปที่คอนโซลได้รับการฟลัชที่แต่ละ printf (โปรดทราบว่าเมื่อ stdout ถูกเปลี่ยนเส้นทางไปยังไฟล์ไลบรารี std มักจะบล็อกการบัฟเฟอร์แทนการบัฟเฟอร์บรรทัดเพื่อให้การแก้ไขข้อผิดพลาด printf การดีบักค่อนข้างยากแม้จะมีการขึ้นบรรทัดใหม่ในตอนท้าย)
Erik Eidt

25
@ErikEidt โปรดทราบว่าคุณควรใช้fprintf(STDERR, …)แทนซึ่งโดยทั่วไปจะไม่ถูกบัฟเฟอร์สำหรับการวิเคราะห์ผลลัพธ์
Deduplicator

4
@Deduplicator การเขียนข้อความวินิจฉัยไปยังสตรีมข้อผิดพลาดนั้นมีข้อเสียเช่นกัน - สคริปต์จำนวนมากถือว่าโปรแกรมล้มเหลวหากมีบางสิ่งเขียนไปยังสตรีมข้อผิดพลาด
Voo

54
@Voo: ฉันจะยืนยันว่าโปรแกรมใด ๆ ที่สมมติว่าเขียนไปยัง stderr บ่งชี้ว่าความล้มเหลวนั้นไม่ถูกต้อง รหัสทางออกของกระบวนการคือสิ่งที่ระบุว่าล้มเหลวหรือไม่ ถ้ามันเป็นความล้มเหลวแล้วออก stderr จะอธิบายว่าทำไม หากกระบวนการออกจากระบบเรียบร้อยแล้ว (รหัสการออกเป็นศูนย์) ดังนั้นเอาต์พุต stderr ควรถูกพิจารณาว่าเป็นข้อมูลที่ให้ข้อมูลสำหรับผู้ใช้ที่เป็นมนุษย์โดยไม่มีความหมายของเครื่องที่แยกวิเคราะห์ได้ (อาจมีคำเตือนที่มนุษย์อ่านได้) ในขณะที่ stdout โปรแกรมอาจเหมาะสำหรับการประมวลผลเพิ่มเติม
Daniel Pryden

23
@Voo: โปรแกรมใดที่คุณอธิบาย ฉันไม่ได้ตระหนักถึงแพคเกจซอฟต์แวร์ที่ใช้กันอย่างแพร่หลายที่มีพฤติกรรมเหมือนที่คุณอธิบาย ฉันรู้ว่ามีโปรแกรมที่ทำ แต่มันก็ไม่เหมือนที่ฉันเพิ่งทำขึ้นการประชุมที่ฉันอธิบายข้างต้น: นั่นคือวิธีที่โปรแกรมส่วนใหญ่ใน Unix หรือ Unix-like งานสิ่งแวดล้อมและความรู้ของฉันวิธี โปรแกรมส่วนใหญ่มักมี แน่นอนฉันจะไม่สนับสนุนโปรแกรมใด ๆ เพื่อหลีกเลี่ยงการเขียนไปยัง stderr เพียงเพราะสคริปต์บางตัวจัดการได้ไม่ดี
Daniel Pryden

73

ในระบบ POSIX (พื้นลินุกซ์ใด ๆ BSD สิ่งที่โอเพนซอร์สระบบที่คุณสามารถหา based) \nสายถูกกำหนดให้เป็นสายอักขระที่ยกเลิกโดยการขึ้นบรรทัดใหม่ได้ นี้เป็นสมมติฐานพื้นฐานทุกเครื่องมือบรรทัดคำสั่งมาตรฐานสร้างเมื่อรวมทั้ง ( แต่ไม่ จำกัด เฉพาะ) wc, grep, sed, และawk vimนี่คือเหตุผลว่าทำไมบางบรรณาธิการ (เช่นvim) มักจะเพิ่ม a \nท้ายไฟล์และทำไมมาตรฐานก่อนหน้าของ C ต้องใช้ส่วนหัวเพื่อลงท้ายด้วย\nอักขระ

Btw: การ\nยกเลิกบรรทัดทำให้การประมวลผลข้อความง่ายขึ้นมาก: คุณรู้ว่าคุณมีบรรทัดที่สมบูรณ์เมื่อคุณมีตัวยุติ และคุณรู้แน่นอนว่าคุณต้องดูตัวละครมากขึ้นถ้าคุณยังไม่พบเทอร์มินัลนั้น

แน่นอนนี่คือด้านอินพุตของโปรแกรม แต่เอาต์พุตของโปรแกรมมักถูกใช้เป็นอินพุตของโปรแกรมอีกครั้ง ดังนั้นผลลัพธ์ของคุณควรเป็นไปตามอนุสัญญาเพื่อประโยชน์ในการอนุญาตการป้อนข้อมูลอย่างราบรื่นในโปรแกรมอื่น ๆ


25
นี้เป็นหนึ่งในการอภิปรายที่เก่าแก่ที่สุดในงานวิศวกรรมซอฟแวร์: มันจะดีกว่าที่จะใช้การขึ้นบรรทัดใหม่ (หรือในภาษาการเขียนโปรแกรมอีกเครื่องหมาย "สิ้นคำสั่ง" ชอบอัฒภาค) เป็นเส้นจุดสิ้นสุดหรือสายคั่น ? ทั้งสองวิธีมีข้อดีข้อเสีย โลกของ Windows ส่วนใหญ่ตัดสินด้วยความคิดที่ว่าลำดับการขึ้นบรรทัดใหม่ (ซึ่งโดยทั่วไปคือ CR LF ที่นั่น) เป็นตัวคั่นบรรทัดและทำให้บรรทัดสุดท้ายในไฟล์ไม่จำเป็นต้องลงท้ายด้วย ในโลกของ Unix แม้ว่าลำดับบรรทัดใหม่ (LF) เป็นตัวยกเลิกบรรทัดและมีหลายโปรแกรมที่สร้างขึ้นตามสมมติฐานนี้
Daniel Pryden

33
POSIX ยังกำหนดบรรทัดเป็น"ลำดับอักขระที่ไม่ใช่อักขระขึ้นบรรทัดใหม่หรือมากกว่าและบวกกับอักขระขึ้นบรรทัดใหม่ที่ยกเลิก "
ท่อ

6
ระบุว่าตามที่ @pipe บอกว่ามันอยู่ในข้อมูลจำเพาะของ POSIX เราอาจเรียกมันว่าทางนิตินัยซึ่งต่างจากde factoตามที่คำตอบแนะนำ?
Baldrickk

4
@Baldrickk ถูกต้อง ฉันได้อัปเดตคำตอบของฉันเพื่อยืนยันมากขึ้นในขณะนี้
cmaster

C ยังทำให้การประชุมนี้สำหรับไฟล์ต้นฉบับ: ไฟล์ต้นฉบับที่ไม่ว่างที่ไม่ได้ลงท้ายด้วยการขึ้นบรรทัดใหม่สร้างพฤติกรรมที่ไม่ได้กำหนด
..

31

นอกจากสิ่งที่คนอื่นพูดถึงแล้วฉันรู้สึกว่ามีเหตุผลที่ง่ายกว่ามากนั่นคือมาตรฐาน เมื่อใดก็ตามที่พิมพ์ไปที่ STDOUT ก็มักจะถือว่าอยู่ในบรรทัดใหม่แล้วจึงไม่จำเป็นต้องเริ่มใหม่ นอกจากนี้สมมติว่าบรรทัดถัดไปที่จะเขียนจะทำในลักษณะเดียวกันดังนั้นจึงเป็นประโยชน์โดยเริ่มต้นด้วยบรรทัดใหม่

หากคุณส่งออกบรรทัดนำหน้าบรรทัดใหม่ผสานกับบรรทัดต่อท้ายบรรทัดใหม่ "มันจะจบลงเช่นนี้:

Trailing-newline-line
Trailing-newline-line

Leading-newline-line
Leading-newline-line
Leading-newline-lineTrailing-newline-line
Trailing-newline-line

Leading-newline-lineTrailing-newline-line
Trailing-newline-line
Trailing-newline-line

... ซึ่งน่าจะไม่ใช่สิ่งที่คุณต้องการ

หากคุณใช้บรรทัดใหม่นำขึ้นบรรทัดเดียวในรหัสของคุณและเรียกใช้ใน IDE เท่านั้นมันอาจไม่เป็นไร ทันทีที่คุณรันในเทอร์มินัลหรือแนะนำรหัสของคนอื่นที่จะเขียนถึง STDOUT ข้างๆโค้ดของคุณคุณจะเห็นผลลัพธ์ที่ไม่พึงประสงค์เช่นด้านบน


2
สิ่งที่คล้ายกันเกิดขึ้นกับโปรแกรมที่ถูกขัดจังหวะในเชลล์แบบโต้ตอบ - หากมีการพิมพ์บรรทัดบางส่วน (หายไปขึ้นบรรทัดใหม่) เชลล์จะสับสนเกี่ยวกับคอลัมน์ที่เคอร์เซอร์เปิดอยู่ทำให้ยากต่อการแก้ไขบรรทัดคำสั่งถัดไป หากคุณไม่เพิ่มบรรทัดใหม่ชั้นนำให้กับของคุณ$PS1ซึ่งจะทำให้เกิดการระคายเคืองหลังจากโปรแกรมทั่วไป
Toby Speight

17

เนื่องจากคำตอบที่ได้รับการโหวตอย่างสูงได้ให้เหตุผลทางเทคนิคที่ยอดเยี่ยมแล้วว่าทำไมการขึ้นบรรทัดใหม่ควรเป็นที่ต้องการฉันจะเข้าหามันจากอีกมุมมองหนึ่ง

ในความคิดเห็นของฉันต่อไปนี้ทำให้โปรแกรมอ่านง่ายขึ้น:

  1. อัตราส่วนสัญญาณต่อเสียงรบกวนสูง (aka เรียบง่าย แต่ไม่ง่ายขึ้น)
  2. แนวคิดสำคัญมาก่อน

จากจุดด้านบนเราสามารถยืนยันได้ว่าการขึ้นบรรทัดใหม่นั้นดีกว่า การขึ้นบรรทัดใหม่กำลังจัดรูปแบบ "สัญญาณรบกวน" เมื่อเปรียบเทียบกับข้อความข้อความควรโดดเด่นและควรมาก่อน (เน้นที่ไวยากรณ์สามารถช่วยได้เช่นกัน)


19
ใช่"ok\n"มันดีกว่า"\nok"...
cmaster

@cmaster: ทำให้ผมนึกถึงได้อ่านเกี่ยวกับ MacOS ใช้ API Pascal สตริงใน C ซึ่งต้อง prefixing "\pFoobar"สายอักขระตัวอักษรทั้งหมดที่มีรหัสการหลบหนีเช่นมายากล
grawity

16

การใช้บรรทัดใหม่ต่อท้ายทำให้การปรับเปลี่ยนในภายหลังง่ายขึ้น

เป็นตัวอย่าง (ไม่สำคัญมาก) ตามรหัสของ OP สมมติว่าคุณต้องสร้างเอาต์พุตก่อนที่ข้อความ "การเริ่มต้น" และเอาต์พุตนั้นมาจากส่วนตรรกะที่แตกต่างกันของรหัสในไฟล์ต้นฉบับที่แตกต่างกัน

เมื่อคุณเรียกใช้การทดสอบครั้งแรกและค้นหา "การเริ่มต้น" ต่อท้ายบรรทัดของผลลัพธ์อื่น ๆ คุณต้องค้นหารหัสเพื่อค้นหาตำแหน่งที่พิมพ์และหวังว่าการเปลี่ยน "การเริ่มต้น" เป็น "\ n การเริ่มต้น "ไม่ผิดรูปแบบของสิ่งอื่นในสถานการณ์ที่แตกต่างกัน

ตอนนี้ให้พิจารณาว่าจะจัดการกับความจริงที่ว่าผลลัพธ์ใหม่ของคุณเป็นตัวเลือกจริง ๆ หรือไม่ดังนั้นการเปลี่ยน "\ nInialializing" บางครั้งก็สร้างบรรทัดว่างที่ไม่ต้องการในตอนเริ่มต้นของเอาต์พุต ...

คุณตั้งค่าสถานะโกลบอล ( ช็อตสยองขวัญ ?? !!! ) ที่บอกว่ามีการแสดงผลก่อนหน้าหรือไม่และทดสอบเพื่อพิมพ์ "การเตรียมใช้งาน" ด้วยตัวเลือกนำหน้า "\ n" หรือคุณออก "\ n" พร้อมกับ เอาต์พุตก่อนหน้านี้ของคุณและปล่อยให้ผู้อ่านโค้ดในอนาคตสงสัยว่าทำไม "การเตรียมใช้งาน" นี้ไม่มี "\ n" นำหน้าเหมือนกับที่ข้อความเอาต์พุตอื่นทำ

หากคุณแสดงบรรทัดใหม่ที่ต่อท้ายตรงจุดที่คุณรู้ว่าคุณมาถึงจุดสิ้นสุดของบรรทัดที่จำเป็นต้องยกเลิกคุณต้องเลี่ยงปัญหาเหล่านั้นทั้งหมด โปรดทราบว่าอาจต้องใช้คำสั่ง put ("\ n") ที่ส่วนท้ายของตรรกะบางส่วนที่ส่งออกชิ้นส่วนต่อชิ้น แต่ประเด็นก็คือคุณจะต้องขึ้นบรรทัดใหม่ในตำแหน่งที่เก่าที่สุดในรหัสที่คุณรู้ว่าคุณต้องการ ทำมันไม่ใช่ที่อื่น


1
หากทุกรายการเอาท์พุทอิสระควรจะปรากฏในบรรทัดของตัวเองบรรทัดใหม่ที่ตามมาสามารถทำงานได้ดี หากควรรวมหลายรายการเมื่อใช้งานได้จริงสิ่งต่าง ๆ ก็ซับซ้อนมากขึ้น หากเป็นประโยชน์ในการป้อนข้อมูลเอาต์พุตทั้งหมดผ่านรูทีนทั่วไปการดำเนินการเพื่อแทรก clear-to-end-of-line ถ้าอักขระตัวสุดท้ายเป็น CR ไม่มีอะไรเลยถ้าอักขระตัวสุดท้ายเป็นบรรทัดใหม่และขึ้นบรรทัดใหม่ถ้าอักขระตัวสุดท้าย มีสิ่งอื่นใดอาจเป็นประโยชน์หากโปรแกรมจำเป็นต้องทำสิ่งอื่นนอกเหนือจากเอาท์พุทลำดับของสายอิสระ
supercat

7

เหตุใดจึงต้องใช้การขึ้นบรรทัดใหม่แทนที่จะนำหน้าด้วย printf

จับคู่ C ข้อมูลจำเพาะอย่างใกล้ชิด

ไลบรารี C กำหนดบรรทัดเป็นลงท้ายด้วยอักขระขึ้นบรรทัด '\n'ใหม่

สตรีมข้อความเป็นลำดับของตัวละครที่ประกอบด้วยบรรทัดแต่ละบรรทัดประกอบด้วยอักขระศูนย์หรือมากกว่ารวมทั้งอักขระบรรทัดใหม่ที่ยกเลิก ไม่ว่าบรรทัดสุดท้ายจะต้องมีอักขระบรรทัดใหม่ที่ยกเลิก C11 §7.21.2 2

โค้ดที่เขียนข้อมูลเป็นบรรทัดจะจับคู่แนวคิดของไลบรารีนั้น

printf("Initializing"); // Write part of a line
printf("\nProcessing"); // Finish prior line & write part of a line
printf("\nExiting");    // Finish prior line & write an implementation-defined last line

printf("Initializing\n");//Write a line 
printf("Processing\n");  //Write a line
printf("Exiting");       //Write an implementation-defined last line

Re: บรรทัดสุดท้ายต้องมีการยกเลิกตัวบรรทัดใหม่ ฉันขอแนะนำให้เขียนขั้นสุดท้าย'\n'ในเอาต์พุตและยอมรับว่าไม่มีอินพุท


ตรวจสอบการสะกด

ตัวตรวจสอบการสะกดของฉันบ่น บางทีคุณก็ทำเช่นกัน

  v---------v Not a valid word
"\nProcessing"

 v--------v OK
"Processing\n");

ฉันเคยปรับปรุงispell.elให้ดีขึ้นเพื่อรับมือกับสิ่งนั้น ฉันยอมรับ\tว่าเป็นปัญหาที่บ่อยขึ้นและสามารถหลีกเลี่ยงได้โดยการแบ่งสตริงออกเป็นโทเค็นหลาย ๆ อัน แต่มันเป็นผลข้างเคียงของงาน "เพิกเฉย" ทั่วไปที่มากขึ้นเพื่อเลือกข้ามส่วนที่ไม่ใช่ข้อความของ HTML หรือเนื้อความหลายส่วน MIME และส่วนที่ไม่ใช่ความคิดเห็นของรหัส ฉันมักจะหมายถึงการขยายไปยังการสลับภาษาที่มีข้อมูลเมตาที่เหมาะสม (เช่น<p lang="de_AT">หรือContent-Language: gd) แต่ไม่เคยได้รับ Round Tuit และผู้ดูแลปฏิเสธแพตช์ของฉันทันที :-(
Toby Speight

@TobySpeight นี่เป็นToit รอบ ispell.elหวังว่าจะพยายามใหม่ของคุณดีขึ้น
chux

4

การขึ้นบรรทัดใหม่มักทำให้การเขียนโค้ดง่ายขึ้นเมื่อมีเงื่อนไขเช่น

printf("Initializing");
if (jobName != null)
    printf(": %s", jobName);
init();
printf("\nProcessing");

(แต่ดังที่ได้มีการจดบันทึกไว้ที่อื่นคุณอาจจำเป็นต้องล้างบัฟเฟอร์เอาต์พุตก่อนที่จะทำขั้นตอนใด ๆ ที่ต้องใช้เวลา CPU มาก)

ดังนั้นกรณีที่ดีสามารถทำได้ทั้งสองวิธีในการทำ แต่โดยส่วนตัวแล้วฉันไม่ชอบ printf () และจะใช้คลาสที่กำหนดเองเพื่อสร้างผลลัพธ์


1
คุณช่วยอธิบายได้ไหมว่าทำไมรุ่นนี้จึงเขียนได้ง่ายกว่ารุ่นที่มีบรรทัดใหม่ต่อท้าย ในตัวอย่างนี้มันไม่ชัดเจนสำหรับฉัน "\nProcessing"แต่ฉันจะได้เห็นปัญหาที่เกิดขึ้นกับการส่งออกต่อไปที่ถูกเพิ่มสายเดียวกับ
Raimund Krämer

เช่นไรมันด์ฉันสามารถเห็นปัญหาที่เกิดขึ้นจากการทำงานเช่นนี้ printfคุณต้องพิจารณาพิมพ์โดยรอบเมื่อโทร ถ้าคุณต้องการให้บรรทัด "การเริ่มต้น" เป็นเงื่อนไขทั้งหมด คุณต้องรวมบรรทัด "Procesing" ในเงื่อนไขนั้นเพื่อให้ทราบว่าคุณควรขึ้นต้นด้วย newline หรือไม่ หากมีการพิมพ์ล่วงหน้าอีกและคุณจำเป็นต้องปรับบรรทัด "การประมวลผล" ตามเงื่อนไขคุณจะต้องรวมการพิมพ์ถัดไปในเงื่อนไขนั้นด้วยเพื่อทราบว่าคุณควรเติมคำขึ้นบรรทัดใหม่ด้วยบรรทัดใหม่และอื่น ๆ สำหรับแต่ละการพิมพ์
JoL

2
ฉันเห็นด้วยกับหลักการ แต่ตัวอย่างไม่ได้ดี ตัวอย่างที่เกี่ยวข้องมากขึ้นคือรหัสซึ่งควรจะส่งออกจำนวนรายการต่อบรรทัด หากผลลัพธ์ควรเริ่มต้นด้วยส่วนหัวที่ลงท้ายด้วย newline และแต่ละบรรทัดควรเริ่มต้นด้วยส่วนหัวอาจเป็นการง่ายกว่าที่จะพูดเช่นif ((addr & 0x0F)==0) printf("\n%08X:", addr);และเพิ่มเงื่อนไขขึ้นบรรทัดใหม่ให้กับเอาต์พุตในตอนท้ายโดยไม่ใช้ รหัสแยกสำหรับส่วนหัวของแต่ละบรรทัดและขึ้นบรรทัดใหม่
supercat

1

การขึ้นบรรทัดใหม่ชั้นนำไม่สามารถทำงานได้ดีกับฟังก์ชั่นห้องสมุดอื่น ๆ โดยเฉพาะputs()และperrorในไลบรารี่มาตรฐาน

หากคุณต้องการพิมพ์บรรทัดที่เขียนไว้ล่วงหน้า (ไม่ว่าจะเป็นค่าคงที่หรือรูปแบบที่มีการจัดรูปแบบไว้แล้วเช่นพร้อมsprintf()) ก็puts()เป็นตัวเลือกที่เป็นธรรมชาติ (และมีประสิทธิภาพ) อย่างไรก็ตามไม่มีทางที่puts()จะจบบรรทัดก่อนหน้าและเขียนบรรทัดที่ไม่ได้ระบุได้ - มันจะเขียนตัวยุติบรรทัดเสมอ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.