זקוק לעזרה, לולאות While וSwitch Case בC. - עמוד 2 - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

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


Stoned Junglist

Recommended Posts

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

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

התוכנה שלי אמורה לקלוט מספר כ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
  • נוצר
  • תגובה אחרונה

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

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

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

קישור לתוכן
שתף באתרים אחרים

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

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

קישור לתוכן
שתף באתרים אחרים

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

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

\r\n

קישור לתוכן
שתף באתרים אחרים

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

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

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

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

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

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

קישור לתוכן
שתף באתרים אחרים

אופס. קבל תיקון - 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.

קישור לתוכן
שתף באתרים אחרים


#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 בתחילת הלולאה הראשית.

תיקנתי , אך הלולאה נשארת אינסופית. :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 במידה והקלט תקין לכו כמו שהיא כתובה כרגע היא מיותרת.

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

קישור לתוכן
שתף באתרים אחרים

ארכיון

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


×
  • צור חדש...