นี่คือโดยปรกติจะคุยกันเรื่องเต็มไปด้วยความเห็นแต่น่าสนใจไม่น้อย ฉันสังเกตุการณ์ที่ใหญ่ส่วนใหญ่ของพวกนั้นต้องไปแล้วเขาตอบกลับมาที่คำถามที่คล้ายกันบนเว็บไซต์นี้ตกลงมาบนด้านข้างของ fgets()
. ฉันเป็นหนึ่งในพวกนั้น ฉันเจอ fgets()
จะดีขึ้นมากที่จะใช้สำหรับผู้ใช้นำเข้าข้อมูลมากกว่า scanf()
กับสองสาข้อยกเว้น scanf()
ถือว่าเป็นคนโดยหลายอย่างที่เป็น รายการย่อยของสิ่งที่เหมาะสมวิธีการจัดการเรื่องของผู้ใช้นำเข้าข้อมูล. ตัวอย่างเช่น
"มันจะบอกคุณว่ามันสำเร็จหรือล้มเหลวแต่สามารถบอกคุณแค่ประมาณอยู่ไหนมันล้มเหลวและไม่ใช่ทั้งหมยังไงหรือทำไม คุณ
มีน้อยมากโอกาสที่จะทำอะไรผิดพลาดในการกู้คืน."
(jamesdlin). แต่ในตอนผลประโยชน์ของพยายามความสมดุลจะเริ่มจาก citing องมาถกเถียงกัน.
สำหรับผู้ใช้นำเข้าข้อมูลนั่นมาจาก stdin
,i.e. ข้อมูลเข้าจากแป้นพิมพ์, fgets()
จะเป็นทางเลือกที่ดีที่สุด มันเป็นมากกว่าให้อภัยใครในนั้นที่ ข้อความ มันอ่านว่าสามารถจะเต็ม validated ก่อนที่ การแปลงคือพยายาม
หนึ่งในไม่กี่ครั้งแล้วโดยใช้รูปแบบของ scanf(): fscanf() จะเป็นไรหรอกที่จะใช้อาจจะเป็นตอนที่กำลังทำการแปลงข้อมูลจากควบคุมแหล่งข่าวของ i.e. จากการอ่านเข้มงวด formatted องแฟ้มกับซ้ำอย่างอื่นฟิลด์
อีกอย่าง, งนี้เปรียบเทียบ ของที่สองสำคัญเพิ่มเติมนายได้เปรียบอะไรบ้างและ disadvantages ของทั้งสองอย่าง
แก้ไข:เพื่อที่อยู่ของปฏิบัติการเพิ่มเติมคำถามเรื่องเลยล้นมาถึง:
"อีกอย่างที่ฉันอยากจะถามคือ:ถึงแม้ตอนที่เราใช้ fgets อะไรเกิดขึ้นถ้าผู้ใช้ป้องตัวอักษรมากกว่าขอบเขต(ฉันหมายถึงเยอะ
ตัวอักษร)มันำเพื่อนชนเลยล้นมาถึง? แล้ววิธีจัดการกับ
คิดว่าคุณไม่เคยถามตัวเอง
[fgets()](https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm เป็นดีๆออกแบบเพื่อป้องกันชนเลยล้นมาถึงเองสามารถทำได้ง่ายๆโดยใช้พารามิเตอร์ของมันเหมาะสม,eg:
char buffer[100] = {0};
...
while fgets(buffer, sizeof buffer, stdin);
นี่จะปกป้องนำเข้าข้อมูลมากกว่ากาดขนาดบัฟเฟอร์ข้อมูลจากการถูกประมวลผล,ดังนั้นกันที่เอ่อล้นออกมา.
ไม่ใช้ scanf()
ป้องกันชนเอ่อล้นออกมาค่อนข้างตรงไปข้างหน้า:ใช้ ความกว้าง specifier ในรูปแบบข้อความ ถ้าคุณอยากจะอ่านข้อมูลสำหรับตัวอย่างและจำกัดข้อมูลขนาดจากผู้ใช้ที่จะ 100 ตัวอักษรแม็กซ์อดรหัสที่จะรวมต่อไปนี้:
char buffer[101] = {0};// includes space for 100 + 1 for NULL termination
scanf("%100s", buffer);
^^^ width specifier
แต่ยังไงกับตัวเลข,เอ่อล้นออกมาคือไม่ค่อยดีโดยใช้ scanf()
. สาธิตให้ดูอจะง่ายอย่างรหัส inputting สองคค่าชี้ให้เห็นว่าในความเห็นหนึ่งต่อไป:
int main(void)
{
int val = 0;
// test with 2147483647 & 2147483648
scanf("%d", &val);
printf("%d\n", val);
return 0;
}
สำหรับคนที่สองค่าของระบบโยนต่อไปนี้:
NON-FATAL RUN-TIME ERROR: "test.c", line 11, col 5, thread id 22832: Function scanf: (errno == 34 [0x22]). Range error
`
นี่คุณต้องอ่านอยู่ในข้อความแล้วทำตามกับข้อความให้จำนวนการแปลงโดยใช้หนึ่งของ strto_()
ฟังก์ชัน: strtol(), strtod(),...). ทั้งคู่รวมความสามารถที่จะทดสอบสำหรับเอ่อล้นออกมา ก่อนที่ จะเกิดวิ่งเวลาแจ้งเตือนหรือเกิดข้อผิดพลาด. ควรจำไว้ว่าการใช้ atoi()
, atod()
ไม่ต้องการจะปกป้องจากเอ่อล้นออกมาเหมือนกัน