שפת C משתנה מסוג CHAR

yos345

New member
שפת C משתנה מסוג CHAR

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

char letter; printf("Welcome to Letters!\n");
do{
printf("Please enter a letter:\n"); scanf("%c", &letter); }while (letter < 'A' || letter > 'z');
למשל, אם אני מכניס 1 אני מקבל פלט כפול של הPRINTF.
אשמח לכמה טיפים בנושא משתני CHAR :)
 

BravoMan

Active member
זה לא קשור ל-char

זה קשור לצורה שבה scanf עובדת: כשאתה לוחץ Enter, יש עוד תו, בלתי נראה - "סוף שורה" שנכנס לקלט.
&nbsp
אמרת ל-scanf לקרוא מהקלט תו אחד בלבד וזה מה שהיא עושה - היא קוראת את ה-1, ומשאיר את תו סוף שורה, התוכנית מגיע לתנאי הלולאה, רואה שזה לא אות, וחוזרת לתחילת הלולאה.
כעת scanf מופעלת שוב, אבל מכיוון שכבר יש תו בקלט - אותו סוף שורה שנותר מהפעם הקודמת, היא לא מבקשת קלט חדש אלא דוחפת אותו למשתנה letter.
והלולאה מתבצעת עוד פעם.
&nbsp
הפתרון הוא להשתמש בפונקציה getchar אחרי scanf כדי להיפתר מהתו המיותר, או לחלופין בפוקנציה fflush עם פרמטר stdin כדי לנקות את חוצץ הקלט (input buffer).
 

BravoMan

Active member
ממש לא בוודאי!

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

yos345

New member
תודה ושאלה נוספת

תודה על הפתרון, השתמשתי בfflash ועובד הכל.

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

לגבי isdigit isalpha, לא הכרתי אותן ואכן אסור לי להשתמש בהן.
אני אבדוק אותן בשביל ידע כללי.

עכשיו לגבי scanf, זה קורה רק עם טיפוס char, למשל עם int אין לי את הפלט הכפול. האם זה בגלל ש char יכול להכיל רק בית 1?
חיפשתי מידע לגבי זה באינטרנט והלכתי לאיבוד.
אפשרי לקבל קישור לאתר שמסביר את ה"תופעות" הללו?
 

BravoMan

Active member
כמה דברים:

1. getchar אכן קולט תו אחד בכל פעם, לכן אם הקלדת כמה תווים, (זכור שספרה שאתה מקליד היא למעשה תו), הוא ימחק רק אחד מהם וישאיר את השאר ל-scanf הבא.
&nbsp
fflush מרוקן את באפר הקלט לחלוטין, לא משנה כמה מידע יש בו.
&nbsp
2. לעניין int:
שוב, זה לא קשור לגודל המשתנה, אלא להתנהגות פונקציית scanf.
&nbsp
הפונקציה הזו יודעת לנתח את הקלט במגוון צורות. כשמבקשים ממנה לקלוט תו בודד עם c% זה כל מה שהיא עושה - לוקחת תו אחד מהקלט.
כשמבקשים ממנה לקלוט מספר עשרוני עם d% היא מתחילה לקרוא תווים עד לרווח או סוף שורה, ולפרש אותם כספרות.
כל עוד הקלט הוא אכן ספרות ו\או סימן - בלבד (אפשר לקלוט גם מספרים שליליים) הפונקציה תאחסן אותו במשתנה שסיפקת.
&nbsp
אם נקלט משהו שאינו מספר הוא ייזרק לפח והתוכנית תמשיך להתבצע בלי שערך המשתנה השתנה.
&nbsp
3. הנה עוד קצת מידע על פונקציית scanf ומה אפשר לעשות איתה:
http://man7.org/linux/man-pages/man3/scanf.3.html
 

yos345

New member
אחלה

הבנתי

תודה רבה :)
 
למעלה