การผสมเอาต์พุตC-style printf()(หรือputs()หรือputchar()หรือ ... ) กับ C ++ - std::cout << ...เอาต์พุตสไตล์ไม่ปลอดภัย หากฉันจำอย่างถูกต้องพวกเขาสามารถมีกลไกการบัฟเฟอร์แยกกันดังนั้นผลลัพธ์อาจไม่ปรากฏตามลำดับที่ต้องการ (ตามที่ AProgrammer กล่าวถึงในความคิดเห็นให้sync_with_stdioระบุสิ่งนี้)
printf()เป็นประเภทที่ไม่ปลอดภัยขั้นพื้นฐาน ประเภทที่คาดไว้สำหรับอาร์กิวเมนต์จะถูกกำหนดโดยสตริงรูปแบบ ( "%d"จำเป็นต้องใช้intหรือสิ่งที่ส่งเสริมการint, "%s"ต้องใช้char*ซึ่งจะต้องชี้ไปที่สตริง C-สไตล์ยกเลิกอย่างถูกต้อง ฯลฯ ) แต่ผ่านผิดประเภทของผลการโต้แย้งในพฤติกรรมที่ไม่ได้กำหนด ไม่ใช่ข้อผิดพลาดที่สามารถวินิจฉัยได้ คอมไพเลอร์บางตัวเช่น gcc ทำงานได้ดีพอสมควรในการเตือนเกี่ยวกับความไม่ตรงกันของประเภท แต่พวกเขาสามารถทำได้เฉพาะในกรณีที่รูปแบบสตริงเป็นตัวอักษรหรือเป็นที่รู้จักกันในเวลารวบรวม (ซึ่งเป็นกรณีที่พบบ่อยที่สุด) - และเช่น คำเตือนไม่จำเป็นต้องใช้ภาษา หากคุณผ่านประเภทของการโต้แย้งที่ไม่ถูกต้องสิ่งเลวร้ายโดยพลการสามารถเกิดขึ้นได้
ในทางตรงกันข้ามกระแส I / O ของ C ++ นั้นปลอดภัยกว่าประเภทมากเนื่องจากตัว<<ดำเนินการโอเวอร์โหลดสำหรับประเภทที่แตกต่างกันมากมาย std::cout << xไม่ต้องระบุประเภทของx; คอมไพเลอร์จะสร้างรหัสที่เหมาะสมสำหรับสิ่งที่ประเภทxมี
ในทางกลับกันprintfตัวเลือกการจัดรูปแบบของ IMHO สะดวกกว่ามาก หากฉันต้องการพิมพ์ค่าเลขทศนิยมด้วยตัวเลข 3 หลักหลังจุดทศนิยมฉันสามารถใช้"%.3f"- และไม่มีผลกับอาร์กิวเมนต์อื่นแม้ในการprintfโทรเดียวกัน ในทางกลับกัน C ++ setprecisionนั้นมีผลกระทบต่อสถานะของกระแสข้อมูลและสามารถทำให้เกิดความสับสนในภายหลังหากคุณไม่ระมัดระวังในการคืนค่ากระแสข้อมูลให้เป็นสถานะก่อนหน้า (นี่คือสัตว์เลี้ยงโกรธส่วนตัวของฉันถ้าฉันไม่มีวิธีทำความสะอาดเพื่อหลีกเลี่ยงโปรดแสดงความคิดเห็น)
ทั้งสองมีข้อดีและข้อเสีย ความพร้อมใช้งานของprintfมีประโยชน์อย่างยิ่งหากคุณมีพื้นหลัง C และคุณคุ้นเคยกับมันมากขึ้นหรือถ้าคุณนำเข้ารหัสต้นฉบับ C ลงในโปรแกรม C ++ std::cout << ...มีความหมายมากกว่าสำหรับ C ++ และไม่ต้องใช้ความระมัดระวังมากนักในการหลีกเลี่ยงประเภทที่ไม่ตรงกัน ทั้งสองเป็น C ++ ที่ถูกต้อง (มาตรฐาน C ++ รวมถึงไลบรารีมาตรฐาน C ส่วนใหญ่โดยการอ้างอิง)
มันอาจจะดีที่สุดที่จะใช้std::cout << ...เพื่อประโยชน์ในการเขียนโปรแกรมภาษา C ++ อื่น ๆ ที่อาจทำงานในรหัสของคุณ แต่คุณสามารถใช้อย่างใดอย่างหนึ่ง - โดยเฉพาะอย่างยิ่งในรหัสร่องรอยว่าคุณกำลังจะโยนออกไป
และแน่นอนว่ามันคุ้มค่าที่จะใช้เวลาในการเรียนรู้วิธีใช้ debuggers (แต่นั่นอาจไม่เป็นไปได้ในบางสภาพแวดล้อม)
printfในโลก C ++? ฉันพลาดอะไรบางอย่างที่นี่?