עבור לתוכן

זקוק לעזרה, לולאות While וSwitch Case בC.

Featured Replies

פורסם
  • מחבר

שלומות! לא פתחתי דיון חדש כי לא רציתי ליצור עומס.

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

התוכנה שלי אמורה לקלוט מספר כChar, ולבדוק כל מקרה: שchar= לערך 1 היא תפעיל תפונקציה, כרגע לא חשוב איזה. ושתגמור להפעילה תחזור לבקש עוד קלט בין 1 ל4.

אותו דבר ש char מקבל 2 ו-3 (פונקציה שונה ב2 ופונקציה שונה ב-3). כשchar יקבל את 4 הוא יסגור את התוכנה.

הבעיה העיקרית שלי היא הנ"ל:

צריך להיות מוכן לאפשרות שהמשתמש יקליד : מספר שלילי, תו מסוים או שתי תווים ואז ילחץ אנטר

עכשיו עם מספר שלילי ותו מסוים שלא בתחום בין 1 ל-4 הסתדרתי. אך הבעיה שלי היא כאשר המשתמש מקליד שתי תווים (45 , 31 וכו') ובכך יוצר בעיה שהתוכנה קולטת בלולאה תו תו ,ולכן במקרה לדוגמא של 31 , קוראת את 1(ובכך מפעילה את הפונקציה 1 ) ולא קוראת את זה כ-31. עכשיו ניסיתי ליצור פונקציה שתחבר את הchar ל-31 ותדע שברגע שהוא מגיע לספר בעל שתי ספרות, יש לבקש מהמשתמש עוד פעם את הקלט, מכיוון שמספר בעל שתי ספרות הוא קלט לא תקין.

לצערי= שאני מקליד פלט שגוי או פלט טוב, התוכנה עושה את המבוקש ואחר כך מבקשת עוד פלט(במקרה וchar מוקלד כ- 4 היא יוצאת מהתוכנה כמבוקש), ולאחר קבלת הפלט השני נתקעת בלולאה אין סופית.

איך אני מתקן זאת?

להל"ן הקוד: (בC כמובן).


#include <stdio.h>
int main()
{
char c,error='n';
int i,selection=0,count=0;
while (c!='\n' || error=='y')
{
scanf("%c",&c);
error='n';
if(c>='0' && c<='9')
selection=10*selection+c-48;
else
{
error='y';
}
++count;
if(count==1)
{
switch(selection)
{
case 1:printf("lol1");error='y';break;
case 2:printf("lol2");error='y';break;
case 3:printf("lol3");error='y';break;
case 4:printf("lol4");error='n';break;
default:printf("error");error='y'; break;
}
}
else
{
error='y';
}
}
}

  • תגובות 51
  • צפיות 5.3k
  • נוצר
  • תגובה אחרונה
פורסם

אתה חייב לקלוט CHAR?

פורסם

^^

העסק היה הרבה יותר פשוט אם היית מראש קולט int (באמצעות d%), או לחילופין לקלוט את כל השורה ב-fgets ואז לעבוד עליה.

פורסם
  • מחבר

לצערי אני צריך לבדוק את כל האפשרויות של קלט שגוי ולכן לקלוט בCHAR ולא INT.

Fgets זה להכניס את השורה לstring לא?

אין אפשרות לתקן זאת לקליטת char?

פורסם

כן, fgets זה לקרוא את כל השורה למחרוזת.

אם אתה רוצה לעבוד עם char, אז שים לב ש-scanf מדלג על רווחים וירידות שורה, ולכן לא יתאים כאן.

במקום זה, עדיף לך לעבוד עם getchar שקורא תווים בלי דילוגים. אבל אם כבר יש לך לולאה שקוראת תווים אחד אחד באמצעות getchar, יהיה יותר פשוט לקרוא את כל התווים במכה אחת (או לפחות בקבוצות) עם fgets, לא?

פורסם
  • מחבר

אני יודע שיהיה יותר פשוט, אבל לצערי אינני יכול להשתמש בStrings.

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

פורסם

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

כרגע, התכנית שלך מאוד נוקשה (אם נתעלם לרגע מכמה באגים קטנים שיש לך). היא דורשת שהמשתמש יכניס רק ספרה אחת ומיד אח"כ enter, בלי שום סימנים אחרים לפני או אחרי (כולל רווחים). מה גם שאם התכנית שלך רצה בסביבת windows, אז אתה צריך להתייחס לכך שסוף שורה מוגדרת ע"י שני תווים רצופים:

\r\n

פורסם
  • מחבר

כן, fgets זה לקרוא את כל השורה למחרוזת.

אם אתה רוצה לעבוד עם char, אז שים לב ש-scanf מדלג על רווחים וירידות שורה, ולכן לא יתאים כאן.

במקום זה, עדיף לך לעבוד עם getchar שקורא תווים בלי דילוגים. אבל אם כבר יש לך לולאה שקוראת תווים אחד אחד באמצעות getchar, יהיה יותר פשוט לקרוא את כל התווים במכה אחת (או לפחות בקבוצות) עם fgets, לא?

מזאת אומרת , אבל scanf קולט הכול..

האם אתה מתווכן שgetchar מדלג על רווחים?אבל אז איך הוא יודע להבדיל בין שתי מספרים? נגיד 21 24.?

המטרה של המתעללים בי היא שהתוכנית תיהיה מושלמת ואני צריך לקלוט מה שצריך רק. ולצערי אני לא מצליח לבנות תוכנה כזאת :'(

פורסם

אופס. קבל תיקון - scanf לא מדלג על רווחים כשהוא קולט char.

לא הבנתי מה הקשר בין דילוג על רווחים להבדלה בין הספרה 4 והספרה 1.

מה זאת אומרת "לקלוט רק מה שצריך"?

פורסם
  • מחבר

אופס. קבל תיקון - scanf לא מדלג על רווחים כשהוא קולט char.

לא הבנתי מה הקשר בין דילוג על רווחים להבדלה בין הספרה 4 והספרה 1.

מה זאת אומרת "לקלוט רק מה שצריך"?

הבעיה שלי, שהבתחלה בניתי תוכנה שפעלה, קלטה char תו אחד אבל אם הוא לא היה בין 1 ל4 אז היא לא רצה וחיכתה לקלט מתאים, אך הבעיה מופיעה כאשר מישהו מזין מספר כמו 41, אז זה קולט תו תו ואז זה קלט את זה כ-4 ואז כ-1 וגרם ללולאה אינסופית ודברים שלא רציתי.

הרעיון שלי לתקן את הדבר היה להפוך את הChar למספר int, ע"י לולאה while ( c!='\n') אך זה נכשל.

הנה התוכנה שתקלוט תווים ותבדוק אם הם לא שלילים או אותיות ודברים שלא צריכים ותכניס בX את המספר שמורכב מהתווים.

 while (c!='\n' || error=='y')
{
error='n';
if (c>='0' && c<='9')
x=10*x+c-48;
else
{
error='y';
while(c!='\n')
{
scanf("%c",&c);
}
}
if(x==0)
error='y';
scanf("%c",&c);
}

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

פורסם

אתה לא צריך כל כך הרבה לולאות וSCANFים.

פורסם
  • מחבר


#include <stdio.h>
int main()
{
char c,error='y',e='y';
int selection=0;
while(e=='y')
{
scanf("%c",&c);
e='n';
while (c!='\n' || error=='y')
{
scanf("%c",&c);
error='n';
if(c>='0' && c<='9')
selection=10*selection+c-48;
else
error='y';
}
switch(selection)
{
case 1:printf("lol1");e='y';break;
case 2:printf("lol2");e='y';break;
case 3:printf("lol3");e='y';break;
case 4:printf("lol4");e='n';break;
default:printf("error");e='y';break;
}
}
}

הפונקציה השלמה, לא פועלת לי ונכנסת ללולאה אינסופית... איך אני פותר את הבעיה? ניסתי הכול, ואני לא מצליח להפעיל את התוכנה כראוי. :s07:

פורסם

א. אחרי הקריאה הראשונה ל-scanf, אתה קורא מיד שוב ל-scanf ובעצם זורק את הערך הראשון שקראת לפח.

ב. אתה לא מאפס את error ואת selection בתחילת הלולאה הראשית.

פורסם
  • מחבר

א. אחרי הקריאה הראשונה ל-scanf, אתה קורא מיד שוב ל-scanf ובעצם זורק את הערך הראשון שקראת לפח.

ב. אתה לא מאפס את error ואת selection בתחילת הלולאה הראשית.

תיקנתי , אך הלולאה נשארת אינסופית. :kopfpatsch: תודה על העזרה המרובה ד"א..


#include <stdio.h>
int main()
{
char c,error='y',e='y';
int selection=0;
while(e=='y')
{
error='0';
selection=0;
scanf("%c",&c);
e='n';
while (c!='\n' || error=='y')
{
error='n';
if(c>='0' && c<='9')
selection=10*selection+c-48;
else
error='y';
}
switch(selection)
{
case 1:printf("lol1");e='y';break;
case 2:printf("lol2");e='y';break;
case 3:printf("lol3");e='y';break;
case 4:printf("lol4");e='n';break;
default:printf("error");e='y';break;
}
}
}

פורסם

הבעיה שלך היא בלולאה הפנימית: נגיד והמשתמש מכניס תו תקין בין 0 ל 9 ו error נשאר n אבל c לא שווה ל \n ואתה נתקע בלולאה אינסופית.

הלולאה הפנימית כרגע בעצם לא עושה כלום, אתה לא קולט שם מחדש ובעצם רק מבצע הצבה ב selection במידה והקלט תקין לכו כמו שהיא כתובה כרגע היא מיותרת.

השאלה היא האם אתה רוצה לקלוט רק ספרה אחת או מס' שלם? ומה אתה רוצה לעשות אם נקלט תו לא תקין (לקלוט חדש, לעשות משהו אחר)?

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים