הי, שאלה טיפשית ב-C

Nי cוני

New member
הי, שאלה טיפשית ב-C

אם אני רוצה לקרוא לתוכנית שלי קלט אל תוך משתנה מטיפוס int, ומכניסים לי 1000000000000000, איך אני יכולה לדעת שהייתה בעיה כלשהי בתוכנית? (איך אני יכולה לבדוק את זה ולטפל, לבקש שוב קלט או משהו כזה)
 

EndersG

New member
שאלה לא טיפשית בכלל!

בדיקות קלט הן דבר חשוב מאוד - ולו רק מסיבות אבטחה. ולשאלתך. דרך אחת (פשוטה מאוד ואני בטוח שלא מושלמת) תקראי את הקלט למחרוזת. בצעי על המחרוזת בדיקה של האורך (strlen )ושכל התווים הם ספרות (isdigit). אז בסוף את יכולה להמיר עם atoi למספר שלם. אפשר גם עם sprintf אבל אני לא ממליץ.
 

Nי cוני

New member
../images/Emo13.gifתודה

בשאלה עצמה לא טיפשית, זה טיפשי שאני לא יודעת את התשובה... הפיתרון שלך נראה קצת מורכב מידי בשביל בעיה כל כך פשוטה. אין אפשרות לתפוס exception או משהו כזה? תודה
 

EndersG

New member
לא - בC אין exception

מה שנהוג לעשות הוא לבדוק את הדברים בעצמך. C היא שפה העובדת ברמה מאוד קרובה לאסמבלי ולעיתים קטעי קוד מסויימים התרגום כמעט מיידי. נסי את מה שאמרתי זה לא אמור לקחת יותר מ10-20 שורות קוד להערכתי. ומרגע שכתבת את זה פעם אחת, זה יכול לשמש אותך תמיד. מניסיוני הדל - אין מה לעשות בC צריך לעבוד קשה.
 
המלצה - לעבוד עם strtol

זוהי פונקציה של הספריה הסטנדרטית. היא תחזיר את הערך הנכון ואם תהיינה שגיאות קלט הפונקציה תעביר זאת דרך המשתנה הגלובלי errno. למשל אם המספר חורג בגודל אז יוחזר ERANGE במשתנה errno יתרון נוסף שיש לפונקציה הזאת הוא שהיא ממירה באופן אוטומטי תחיליות 0x או '0' לבסיס 16 ו8- בהתאמה. קוד לדוגמא:
char* endp; long n = strtol("112233445566778899", &endp, 0); if (errno == ERANGE) perror("ERANGE in Conversion"); else if (errno == EINVAL) perror("EINVAL Error in Conversion");​
 

Nי cוני

New member
ממש תודה

אבל לא הבנתי איך אני יכולה להשתמש בפונקציה זו בשביל לקרוא קלט מהמשתמש ולא להמציא מספר בתוכנית עצמה
 
שימי לב מה הקלט של הפונקציה

ההכרזה של הפונקציה ב-stdlib.h היא כדלקמן:
long strtol(const char *nptr, char **endptr, int base);​
הפונקציה מקבלת בפרמטר הראשון מחרוזת (ה-const מלמד שהפונקציה לא תשנה אותו). המחרוזת יכולה להגיע ממגוון מקורות. למשל מה שכתבתי בתשובה הקודמת, או קריאה של קלט (מקובץ או מ-STDIN ) לתוך מערך תוים ואז להעביר את מערך התוים כפרמטר ראשון לפונקציה. בעצם את צריכה לכתוב קוד שמדביק בין שתי פונקציות ספריה. א. קריאה של קלט מקובץ ב. העברה של הקלט הזה לפונקציה strtol קריאת הקלט וההמרה למספר הן פונקציות מובנות בספריה הסטנדרטית. כל שנותר לך לעשות הוא ל"הדביק" ביניהן בהצלחה
 

erezsh

New member
אין צורך לבצע בדיקת אורך

אם אתה מגביל את האורך בעת קבלת הקלט (נניח אם משתמשים ב-fgets). בנוסף, אני מסכים עם הבחורצ'יק השני, בנוגע לכך שעדיף להשתמש ב-strtol אם אינך סומך על הקלט.
 

DNile

New member
אי אפשר פשוט לתת disclaimer:

אם אני לא יכול לסמוך על הקלט - אתם אל תסמכו על הפלט?
 

erezsh

New member
הלוואי והיה אפשר

משתמשים לא קוראים disclaimers, ולא סומכים על הקלט של עצמם. אבל הבעיה האמיתית היא כשהקלט לא בהכרח מגיע מבעל התוכנית..
 

DNile

New member
אפשר לשים message box גדול

בהתחלת התוכנית. והבן אדם היחידי שמנסה לתת קלט רע לתוכנית שלך זה איזה בוחן מטומטם שלא יודע על מה להוריד לך נקודות, אז הוא מחליט לדחוף לך מספרים ואותיות, וחורג לך מבאפרים.
 

DNile

New member
חחחחחחח.. האמת שלא..

הבוחנים שהיו לי עד עכשיו לפרויקטים השונים שעשיתי נראו ככה: "טוב, צ'מע, אני לא כל כך יודע MFC, אבל בוא תראה לי שיש לך הערות כמו שצריך בקוד"... פשוט נזכרתי באיזה מטלה מצחיקה שהייתה לי בקורס מבוא למדעי המחשב, שבו ציינו ש:"אם אתה מניח הנחות על הקלט, ציין זאת". אז כתבתי: "הנחה על הקלט - הוא תקין".
 

selalerer

New member
תשכחי כל מה שאמרו לך.

לכל פונקציית קלט יש דרך להודיע לך אם הקלט היה מוצלח או לא. זה יכול להיות בערך מוחזר מהפונקציה או קביעה של ערך גלובלי (כמו errno) לערך מסויים. את רק צריכה תיעוד טוב של פונקציית הקלט שאת משתמש בה ושם יהיה כתוב לך מה יקרה במצב כמו שאתה מתארת (או כל מצב אחר אפשרי). אין צורך לכתוב בעצמך פונקציית קלט חדשה.
 
למעלה