פורסם 2006 בנובמבר 2719 שנים שלום לכם אנשים יקרים...יש לי בעיה עם תוכנית C שכתבתי, התוכנית אמורה לקלוט חשבונות בנק של אנשים לתוך רשימה, והיא עובדת כך:כאשר מפעילים אותה היא מבקשת ממך להכניס פקודה, כאשר מכניסים פקודת new מתקבל מסך שמאפשר לך להקליד את הפרטים של החשבון (מקלידים הכל בשורה עם רווחים) כאשר לוחצים אנטר החשבון נקלט. ואז אמורה להופיע שורה המבקשת ממך שוב להקיש פקודה. הבעיה היא שהשורה הנ"ל מופיעה פעמיים משום מה, וזה קורה אך ורק לאחר פקודת new.צירפתי לכאן את הקוד כאשר כל החלקים הלא רלוונטים לפקודת new הוכנס לתוך הערה ולמעשה השארתי רק את החלק הבעייתי, הקוד המצורף תומך רק בפקודת new שכן רק היא הבעייתית ואין צורך בהעתקת כל הקוד, הקוד ניתן לקימפול ובדיקה.שימו לב הפרוצדרות שיוצרות את הבעיה הן newAccount_first ו newAccount_KeyBoard#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct CustomerData { int id; char firstName[256]; char lastName[256]; char cellPhone[256]; int balance; struct CustomerData* next; } CustomerData;/*char* strcut (char* string, int n){ int i=0; while (i<n){ string++; i++; } return string;}*/inline void newAccount_first (CustomerData* head){ fopen("stdin","r"); char f_name[256]; // f_name=(char*) malloc (sizeof(char)); char l_name[256]; // l_name=(char*) malloc (sizeof(char)); char c_phone[256]; // c_phone=(char*) malloc (sizeof(char)); int id,bal; printf ("ID First Name Last Name Cell Phone Balance \n"); if (scanf("%d %s %s %s %d",&id,f_name,l_name,c_phone,&bal)!=5) { printf ("wrong parameters\n"); /*free (f_name); free (l_name); free(c_phone);*/ return; } head->id=id; strncpy(head->firstName,f_name,strlen(f_name)); strncpy(head->lastName,l_name,strlen(l_name)); strncpy(head->cellPhone,c_phone,strlen(c_phone)); head->balance=bal; /*free (f_name); free (l_name); free(c_phone);*/ return;}inline void newAccount_KeyBoard (CustomerData *new, CustomerData* head){ char *f_name; f_name=(char*) malloc (sizeof(char)); char *l_name; l_name=(char*) malloc (sizeof(char)); char *c_phone; c_phone=(char*) malloc (sizeof(char)); int id,bal; printf ("ID First Name Last Name Cell Phone Balance \n"); if (scanf("%d %s %s %s %d",&id,f_name,l_name,c_phone,&bal)!=5) { printf ("wrong parameters\n"); /*free (f_name); free (l_name); free(c_phone);*/ return; } new->id=id; strcpy(new->firstName,f_name); strcpy(new->lastName,l_name); strcpy(new->cellPhone,c_phone); new->balance=bal; while ((*head).next!=NULL) head=head->next; head->next=new; free (f_name); free (l_name); free(c_phone); return; } /*void printAccounts (CustomerData *top){ CustomerData *head=top; printf ("ID First Name Last Name Cell Phone Balance \n"); while (head!=NULL){ printf ("%d %15s %23s %23s %23d\n",(*head).id, (*head).firstName, (*head).lastName, (*head).cellPhone, (*head).balance); head=head->next; } }void totalCash (CustomerData* top){ CustomerData *head=top; int cash; cash=0; while (head!=NULL){ cash=cash + (*head).balance; head=(*head).next; } printf ("%d\n",cash);}void charge (CustomerData* top){ CustomerData *head=top; while (head!=NULL){ (*head).balance=(*head).balance - 5; head=(*head).next; }}void favoriteAccount(CustomerData* top){ CustomerData* head=top; CustomerData *fav; fav=head; head=(*head).next; printf("Favorite Customer Is:\n"); printf ("ID First Name Last Name Cell Phone Balance \n"); while (head!=NULL){ if ((*fav).balance<(*head).balance) fav=head; head=(*head).next; } printf("%d %15s %23s %23s %23d\n ",(*fav).id,(*fav).firstName,(*fav).lastName,(*fav).cellPhone,(*fav).balance) ;}void IDSearch(int ID, CustomerData* top){ CustomerData *head=top; CustomerData *found=NULL; while (head!=NULL){ if ((*head).id == ID) found = head; head=(*head).next; } if (found==NULL) { printf("Contact was not found. \n"); return; } printf("the cellularphone for %d is %s \n",ID,(*found).cellPhone);}*/int main () { char* command; CustomerData* first=NULL; while (1>0) { command=(char*) malloc (256); printf("Enter Your Command\n"); fgets(command,256,stdin); /*if (strncmp(command,"print",5)==0){ if (first==NULL) { printf("Account List Empty.\n"); continue; } printAccounts(first); continue; }*/ if (strncmp(command,"new",3)==0){ if (first==NULL) { first=(CustomerData*) malloc(sizeof(CustomerData)); newAccount_first(first); continue; } CustomerData* toBeEntered=(CustomerData*) malloc(sizeof(CustomerData)); newAccount_KeyBoard(toBeEntered,first); continue; }/* if (strncmp(command,"charge",6)==0){ if (first==NULL) { printf ("Account List is Empty"); continue; } charge(first); continue; } if (strncmp(command,"favorite",8)==0){ if (first==NULL) { printf("Account List is Empty"); continue; } favoriteAccount(first); continue; } if (strncmp(command,"total",5)==0){ if (first==NULL) { printf ("Account List is Empty"); continue; } totalCash(first); continue; } if (strncmp(command,"contact",7)==0){ if (first==NULL) { printf ("Account List is Empty"); continue; } IDSearch(atoi(strcut(command,8)),first); continue; }*/ free (command); if (strncmp(command,"exit",4)==0) exit(0); } exit(0);}
פורסם 2006 בנובמבר 2719 שנים תחליף את השורה:fgets(command,256,stdin);בשורה:scanf("%s", command);הבעיה היא שבפעם השניה שהוא מגיע ל-fgets הוא קולט את ה-enter מהפעם הראשונה, ואז הוא פשוט ממשיך לפעם הבאה של הלולאה.
פורסם 2006 בנובמבר 2719 שנים אתה יכול לנסות להשתמש בfflush(stdin);בסוף אתה משחרר את command ואחר כך בודק אם זה exit? לא רצוי.בכלל, אני ממליץ לך שcommand לא יוקצה באופן דינאמי.
פורסם 2006 בנובמבר 2719 שנים מחבר תחליף את השורה:fgets(command,256,stdin);בשורה:scanf("%s", command);הבעיה היא שבפעם השניה שהוא מגיע ל-fgets הוא קולט את ה-enter מהפעם הראשונה, ואז הוא פשוט ממשיך לפעם הבאה של הלולאה.זה יוצר בעיה אחרת, כי עכשיו אם אתה מכניס פרמטר שגוי (לדוגמא סטרינג בשביל ID) אז השורה שמבקשת פקודה מופיעה ארבעה פעמים ולא פעם אחת.שימוש ב- fflush על מנת לנקות את הבאפר גם לא עוזר...
פורסם 2006 בנובמבר 2719 שנים לא קראתי בעיון את הקוד, אבל יתכן שהבעיה היא שהמחזורזת שנקראה מכילה רק new-line או רק רווחים. scanf מחזירה את מספר השדות שהיא קראה. כך שאם היא מחזירה 0 סימן שקראת שורה ריקה, או רק רווחים. תנסה משהו כמו: while ( scanf( "%s", command ) != 1 ){ /* do nothing */ } אבל תבדוק קודם מה נחשב "שדה" כשמדובר במחרוזת. לא השתמשתי ב-scanf כבר שנים
פורסם 2006 בנובמבר 2719 שנים אני הייתי ממליץ להחליף את קטעי הקוד האלה: if (scanf("%d %s %s %s %d",&id,f_name,l_name,c_phone,&bal)!=5) { printf ("wrong parameters\n"); /*free (f_name); free (l_name); free(c_phone);*/ return; }במשהו כזה: while (scanf("%d %s %s %s %d",&id,f_name,l_name,c_phone,&bal)!=5) { scanf("%s", f_name); /* Empty buffer*/ printf ("wrong parameters\n"); printf ("ID First Name Last Name Cell Phone Balance \n"); }
פורסם 2006 בנובמבר 2719 שנים מחבר אני הייתי ממליץ להחליף את קטעי הקוד האלה: if (scanf("%d %s %s %s %d",&id,f_name,l_name,c_phone,&bal)!=5) { printf ("wrong parameters\n"); /*free (f_name); free (l_name); free(c_phone);*/ return; } במשהו כזה: while (scanf("%d %s %s %s %d",&id,f_name,l_name,c_phone,&bal)!=5) { scanf("%s", f_name); /* Empty buffer*/ printf ("wrong parameters\n"); printf ("ID First Name Last Name Cell Phone Balance \n"); } אוקיי אז ככה, קצת עדכונים. התיקון שהוצע כאן גורם ללואה אינסופית, לא סימפטי. לבסוף מצאתי פתרון בעזרת חבר. כמו שנאמר כאן, הבעיה היא שכאשר קולטים פרמטרים מתוך scanf ו- gets אז יש שאריות או שהתחום לא סגור או משהו כזה, בכל מקרה זה מה שכנראה יצר את הבעיה, אז על מנת לעקוף אותו מצאנו פתרון מגעיל למדי לקלוט באמצעות fgets את כל הפרמטרים לסטרינג אחד ואז לפרק אותו באמצעות sscanf שקולט את הסטרינג ומתייחס אליו בדיוק כמו ש-scanf מתייחס לקלט סטנדרטי. תודה בכל מקרה על העזרה.
פורסם 2006 בנובמבר 2719 שנים התיקון שהוצע כאן גורם ללואה אינסופית, לא סימפטי. הרצתי את זה אצלי וזה עבד מצויין :
ארכיון
דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.