בדיקת קלט - שפת C - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

בדיקת קלט - שפת C


sharonp

Recommended Posts

אהלן!

עשיתי קורס בשפת C לפני שנה וחצי ושכחתי חלק מהדברים, או שסתם נהייתי חלוד.

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

אני יכול לעשות משהו בסגנון של:

number_1 != (int)number_1

ומה באשר לבדיקה אם הוכנס תו ולא מספר?

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

טוב יש לי בעיה אחרת שהיא קצת חוזרת על עצמה.

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


double f_price=0, f_quan=0, b_quan=0;
char f_type;

printf("Choose a flower:");
scanf("%ch\n",&f_type);

switch (f_type) {
case 'D':
f_price_=1.35;
break;
case 'R':
f_price=4.30;
break;
default:
printf("ERROR");
return 1;
}

printf("Quantity:");
scanf("%lf\n",&f_quan);
if (f_quan < 0) {
printf("ERROR");
return 1;}
if (f_quan != (int)f_quan){
printf("ERROR");
return 1;}

:(

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

הממ כתבתי CH במקום C..

שיניתי עכשיו, והפעם מה שכתבתי קורה בבקת קלט הראשונה (של האות) - אני מכניס את הקלט וזה לא ממשיך הלאה

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

עריכה: הבנתי שזו טעות לכתוב n/ אחרי ה scanf ותיקנתי.. :\

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

אוקיי, בעיה חדשה:

אותה 'התקעות' כמו ממקודם, הפעם ב SCANF הזה.

אני רוצה לקבל קלט בצורה של DIST.DAY כלומר מספר נקודה מספר כשעל כל אחד מהמספרים יש תנאים משלו, וחייבת להיות נקודה ביניהם אחרת התכנית מסתיינת.

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

printf("Enter distance:");
scanf("%lf%c%lf",&DIST,&dot,&DAY);
if (dot != '.') {
printf("ERROR");
return 1;}
if ((DIST < 0) || (DIST != (int)DIST)) {
printf("ERROR");
return 1;}

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

אופציה אחת היא להשתמש בתבנית לקטל, למשל, SEPERATOR של '.':

scanf("%lf.%lf",&DIST,&dot,&DAY);

*שים לב טוב טוב לנקודה ששמתי בין שני ה %lf

אבל זה עדיין לא פותר לך את הבעיה של בדיקות הקלט.

אני במקומך הייתי את הקלט כמחרוזת ובודק אותה תו תו.

למשל, אין לך ממש אפשרות לבדוק אם המשתמש קלט תו במקום מספר, כי אם הוא קולט תו, ומכניס אותו למשתנה שהוא LONG, אז פשוט ייכנס לשם המספר שמייצג את התו, למשל אם הוא הקליד את התו '=', אז הוא יומר לערך ה ASCII שלו (בוא נגיד 129), וזה מה שיישב לך במשתנה.

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

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

היי שלומפי

כששיניתי את השורה לזו שכתבת זה לא עבר את הבדיקות..

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

בקשר לבדיקת קלט של תוים, אם אני דורש שזה יהיה נקודה באמצע שהערך ASCII שלה הוא 46 אני יכול לקלוט char כמו שעשיתי ולהשוות את ערך ה int שלו יחסית לערך int של נקודה (46)

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

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

הייתה טעות קטנה בקוד שכתבתי לך.

שכחתי להוריד את ה &dot

אבל זה עדיין לא פותר לך את הבעיה של בדיקות התקינות.

אני לא חושב שאתה יכול לקלוט ככה מספר תו מספר (צמודים)

אתה חייב רווחים בינהים.

כתבתי לך קוד שעושה את זה בעזרת קליטת מחרוזת ובדיקה שלה תו תו, תוך כדי המרה של הספרות למספרים לתוך DIST ו DAY.

	long DIST=0, DAY=0;
int length,mul,i,j,error=0;
char input[50];
int error;

gets(input);
length=strlen(input);
for (i=0; i<length; i++)
{
if (input[i]=='.')
{
for (j=length-1, mul=1; j>i && !error; j--, mul*=10)//check for valid number AFTER dot
if (!(input[j]>='0' && input[j]<='9'))
error=1;
else
DAY+=(input[j]-'0')*mul; //sum the right digits to DIST
for (j=i-1, mul=1; j>=0 && !error; j--,mul*=10)//check for valid number BEFORE dot
if (!(input[j]>='0' && input[j]<='9'))
error=1;
else
DIST+=(input[j]-'0')*mul; //sum the left digits to DAY
break;
}
}

if (error || i==length) //numbers not valid, or no DOT found
{
printf("error");
return 1;
}

if ((DIST < 0) || (DIST != (int)DIST))
{
printf("ERROR");
return 1;
}
printf("%ld.%ld",DIST, DAY);

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

אתה קולט שני מספרים DOUBLE? ובינהים אתה רוצה לקלוט את התו '.' שמפריד בינהים?? או שני מספרים רגילים מופרדים ע"י נקודה (כי זה מה שהקוד שכתבתי יעשה)

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

בוקר אור שלומפי

תודה רבה על ההשקעה! מסתבר שזה היה יותר פשוט מכך..

אתה הצעת

scanf("%lf.%lf",&DIST,&dot,&DAY);

והבעיה היתה שזה הכניס את כל הביטוי למשל 15.3 (כש 15 ו-3 הם שני מספרים נפרדים מופרדים על ידי נקודה) לתוך ה lf הראשון. זה נפתר אם משנים את זה ל

scanf("%d.%d",&DIST,&dot,&DAY);

:kopfpatsch:

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

ניסיתי לעבור עליו בדקדקנות ולעצור אותו אחרי כל מיני שורות כדי לראות עד איפה הוא מתפקד ואני לא עולה על הבעיה.

/*4*/
printf("Enter shipping distance:");
scanf("%d.%d", &DIST, &DAY);
if ((DAY < 0) || (DAY > 0 && DAY < 1) || (DAY > 7)) {
printf("ERROR");
return 1;}
if (DIST==0){
ship_price=0;}
else if (DIST <= 25){
ship_price=((3.0/7)*DIST);}
else if (DIST > 25){
ship_price=((3.0/7)*25+(2.0/7)*(DIST-25));}

/*5*/
if (DIST == 0) {
printf("Receipt:\n");
tmp=(f_price_per*f_quan)+b_quan;
printf("Flowers = %.2lf\n", tmp);
printf("Shipping on day %.lf = %.2lf\n", DAY, ship_price);
printf("Total = %.2lf\n", tmp+ship_price); }

else {
printf("Speedy shipping:");
answer = getchar();
switch (answer) {
case 'Y':
delivery=25;
break;
case 'N':
delivery=0;
break;
default:
printf("ERROR");
return 1;}

printf("Receipt:\n");
tmp=(f_price_per*f_quan)+b_quan;
printf("Flowers = %.2lf\n", tmp);
tmp=ship_price+delivery;
printf("Shipping on day %.lf = %.2lf\n", DAY, tmp);
printf("Total = %.2lf\n", tmp+ship_price);
}

בחלק שמסומן בתור *4* הכל בסדר, הבעיה היא שהוא לא נכנס לחלק החמישי ולבדיקת קלט הבאה אלא מסיים את התכנית (הכנסתי ערך ל DIST שונה מאפס לכן אמור להיות עוד קלט)

תודה!

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

זהו, אמרתי לך שלא ממש הבנתי למה אתה קולט שני DOUBLE עם הפרדה של נקודה בין שניהם.

לגבי הקטע החמישי שלא עובד לך, זה בגלל שאחרי שאתה קולט עם ה SCANF בקטע 4, ולוחץ ENTER, אז הוא נשאר ב BUFFER של STDIN, ואז GETCHAR שולף אותו ושם לך אותו ב ANSWER, בלי לחכות לקלט ממך.

אחרי השורה של SCANF, תנקה את ה BUFFER:

fflush(stdin);

או לחלופין, להשתמש ב ()getch במקום ב ()getchar

עדיף אבל לא להשתמש ב getch כי זו לא פונקציה סטנדרטית של השפה. (יש קומפיילרים שלא יכירו אותה).

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

ארכיון

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

×
  • צור חדש...