>> ลำโพง 1: ลองเขียนโปรแกรมที่ ได้รับสายจากผู้ใช้โดยไม่ต้อง
ใช้ CS50 ห้องสมุด GetString ฟังก์ชั่น
การทำเช่นนี้เราจะไปข้างหน้าและใช้ scanf ฟังก์ชั่นที่ GetString
ฟังก์ชั่นการใช้จริง ภายใต้กระโปรงหน้ารถ
แต่ฉันจะทำเช่นนี้จงใจ ในทางรถ
ฉันจะทำในทางที่ผมคิดว่า จะเป็นที่ถูกต้อง แต่มันกลับกลายเป็นว่า
สมมติฐานของฉันไป เป็นค่อนข้างสมบูรณ์ทีเดียว
และในความเป็นจริงอันตรายมาก
เพราะข้อบกพร่องอย่างหนึ่งที่ฉันจะ ทำให้สามารถใช้ประโยชน์โดยฝ่ายตรงข้าม
ดังกล่าวว่าเครื่องหรือโปรแกรมของคุณ สามารถนำไปที่อาจเกิดขึ้น
>> ขอเริ่มต้นดังต่อไปนี้
ก่อนขอประกาศสตริงของเรา หรือที่เรียกว่าเป็นดาวถ่าน,
และเรียกมัน
ช่วยให้ต่อไปแจ้งให้ผู้ใช้สตริงที่ เช่นเดียวกับสตริง "โปรด". และ
ตอนนี้ขอได้รับสายจากผู้ใช้ ใช้ scanf พูดได้นำมาอ้าง "% s." ใน
คำอื่น ๆ ที่ขอแจ้ง scanf เราว่า ในความเป็นจริงไม่คาดหวังที่จะได้รับสาย
จากผู้ใช้
>> แต่ตอนนี้เราจำเป็นต้องบอก scanf สิ่งหนึ่ง ๆ -
ที่จะนำสตริงที่ ผู้ใช้ให้
ดีฉันจะค่อนข้างเพียงแค่เริ่มต้น ด้วยเครื่องหมายจุลภาค s ระบุว่าฉันต้องการ
scanf จะนำสตริงมี
ฉันต่อไปจะพิมพ์ออกมาบางสิ่งบางอย่าง เช่น printf "ขอบคุณสำหรับ% s
เครื่องหมายจุลภาค n. "และเช่นเคยผม จะผ่านในสตริง, s
ตอนนี้ขอบันทึกรวบรวมและใช้นี้ โปรแกรมและดูว่าเราไม่สามารถทำให้เกิดการ
ปัญหาที่ผมคาดการณ์ไว้
>> ทำให้ scanf-1
./scanf-1
String โปรด
ขอให้สิ่งที่ต้องการ "สวัสดี". "ขอบคุณสำหรับ null." อืมที่ไม่
สิ่งที่ผมคาดหวังว่า
ดังนั้นสิ่งที่เกิดขึ้นที่นี่
>> ดีก็จะเปิดออกเพราะเราประกาศ ในฐานะดาวถ่าน แต่เราไม่ได้
จัดเก็บจริงในที่อยู่ของ ก้อนที่เกิดขึ้นจริงของหน่วยความจำ scanf ไม่ได้
มีที่ใดก็ได้ที่จะวางสาย ที่ผู้ใช้พิมพ์ค่ะ
อันที่จริงหากผู้ใช้จะพิมพ์ได้ในตอนนี้ สตริงนานกว่า "สวัสดี"
ตัวอย่างเช่นหลายบรรทัดของข้อความหรือ หลายย่อหน้าของข้อความก็ค่อนข้าง
เป็นไปได้ว่าเราอาจจะก่อให้เกิดการ เรียกว่าความผิดส่วน
>> เพราะ scanf จะไม่ทราบว่า ผมยังไม่ได้ใส่จริงที่อยู่
ภายในของส
แต่ก็จะไปดูค่าบางอย่าง ในวินาที, รูปแบบของบางชิ้นที่อาจ
ดีมากเป็นค่าขยะ มีเพียงแค่โอกาส
scanf และยังจะพยายามที่จะเขียน สตริงผู้ใช้ไปยังที่อยู่ที่
แม้ว่าจะเป็นค่าขยะซึ่ง แน่นอนอาจทำให้เกิดความผิดพลาด
>> ดังนั้นเราจึงมีวิธีการที่จะแก้ไขปัญหานี้