עבור לתוכן

עזרה ב-C.

Featured Replies

פורסם

שלום לכם אנשים יקרים...

יש לי בעיה עם תוכנית 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);
}

פורסם

תחליף את השורה:


fgets(command,256,stdin);

בשורה:


scanf("%s", command);

הבעיה היא שבפעם השניה שהוא מגיע ל-fgets הוא קולט את ה-enter מהפעם הראשונה, ואז הוא פשוט ממשיך לפעם הבאה של הלולאה.

פורסם

אתה יכול לנסות להשתמש בfflush(stdin);

בסוף אתה משחרר את command ואחר כך בודק אם זה exit? לא רצוי.

בכלל, אני ממליץ לך שcommand לא יוקצה באופן דינאמי.

פורסם
  • מחבר

תחליף את השורה:


fgets(command,256,stdin);

בשורה:


scanf("%s", command);

הבעיה היא שבפעם השניה שהוא מגיע ל-fgets הוא קולט את ה-enter מהפעם הראשונה, ואז הוא פשוט ממשיך לפעם הבאה של הלולאה.

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

שימוש ב- fflush על מנת לנקות את הבאפר גם לא עוזר...

פורסם

לא קראתי בעיון את הקוד, אבל יתכן שהבעיה היא שהמחזורזת שנקראה מכילה רק new-line או רק רווחים.

scanf מחזירה את מספר השדות שהיא קראה. כך שאם היא מחזירה 0 סימן שקראת שורה ריקה, או רק רווחים.

תנסה משהו כמו:


while ( scanf( "%s", command ) != 1 )
{ /* do nothing */ }

אבל תבדוק קודם מה נחשב "שדה" כשמדובר במחרוזת. לא השתמשתי ב-scanf כבר שנים :)

פורסם

אני הייתי ממליץ להחליף את קטעי הקוד האלה:


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");
}

פורסם
  • מחבר

אני הייתי ממליץ להחליף את קטעי הקוד האלה:


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 מתייחס לקלט סטנדרטי.

תודה בכל מקרה על העזרה. :)

פורסם

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

הרצתי את זה אצלי וזה עבד מצויין ::)

ארכיון

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

דיונים חדשים