0

私は何度もグーグルで検索しましたが、私の質問/問題に対する具体的な答えを見つけることができません。私はfgets()がgets()と同様にそれを許可することを知っています。しかし、私がそれを複数回行うと、常にエラーが発生します。複数回の意味は、たとえば、彼の名、ミドルネーム、1つ以上の文字列の名前を尋ねたい場合です。

fgets()を動作させることができないので、getsを使用して取得したと思いますが、プログラムにいくつかのバグがあります。だから、私がしたよりも良い解決策を求めたいです。とにかく、ここに部分的なコードがあります:

BST *insert(BST *root, BST *temp){
    if(root == NULL) root = temp; //empty
    else{
        temp->parent = root;
        //if true i = 1, else i = 0
        int i = root->employee.emnumber <= temp->employee.emnumber;
        //recurse
        root->child[i] = insert(root->child[i], temp);
    }
    return root;
}

int checknum(BST *root, int num){
    if(root == NULL){
        if(num <= 99999 && num >= 1) return 0;
        else return 1;
    }
    if(root->employee.emnumber == num || num > 99999 || num < 1) return 1;

    int i = root->employee.emnumber <= num;
    checknum(root->child[i], num);
}

BST *add(BST *root){
    int invalid = -1;
    BST *temp = malloc (sizeof (BST) );
    temp->child[0] = temp->child[1] = temp->parent = NULL;

    printf("\n\tADD EMPLOYEE INFORMATION\n");
    printf("\nEnter Employee Number: ");
    scanf("%d", &(temp->employee.emnumber) );
    invalid = checknum(root,temp->employee.emnumber);
    if(invalid) printf("\nInvalid Input!\n(Either your input is not a 5-digit number or the employee number is already in the database)\n\n");
    else{
        printf("\nFull Name| First Name: ");
        getchar();
        gets(temp->employee.emname.fn);
        //printf("%d\n", strlen(temp->employee.emname.fn));
        if(strlen(temp->employee.emname.fn) > max) printf("Invalid Input!\n(Input only %d characters)\n", max);
        else{
            printf("           Middle Name: ");
            gets(temp->employee.emname.mn);
            if(strlen(temp->employee.emname.mn) > max) printf("Invalid Input!\n(Input only %d characters)\n", max);
            else{
                printf("           Last Name: ");
                gets(temp->employee.emname.ln);
                if(strlen(temp->employee.emname.ln) > max) printf("Invalid Input!\n(Input only %d characters)\n", max);
                else{
                    printf("\nBirth Date| Month: ");
                    scanf("%d", &(temp->employee.bdate.month) );
                    printf("            Day: ");
                    scanf("%d", &(temp->employee.bdate.day) );
                    printf("            Year: ");
                    scanf("%d", &(temp->employee.bdate.year) );
                    printf("\nCurrent Address: ");
                    scanf("%s", temp->employee.address);
                    printf("\nMonthly Gross Salary: ");
                    scanf("%d", &(temp->employee.salary) );
                    printf("\nHire Date| Month: ");
                    scanf("%d", &(temp->employee.hired.month) );
                    printf("           Day: ");
                    scanf("%d", &(temp->employee.hired.day) );
                    printf("           Year: ");
                    scanf("%d", &(temp->employee.hired.year) );
                    root = insert(root, temp);
                }
            }
        }
    }
}

バグは、addに無効な番号を入力した場合、従業員番号に5を入力したが、従業員番号5がすでに存在する場合、プログラムはすでに従業員5が存在すると表示しますが、従業員リストを印刷すると従業員5は存在しません。addに5を再度入力しても、employee 5が削除されたため、プロンプトは表示されません。delete関数を呼び出さなかったため、削除方法はわかりません。誰か助けてください。

編集:checknumを削除し、検索機能で削除を検索しました:検索のコードは次のとおりです:

BST *search(BST *root, int x){
    int i;
    if(root == NULL || root->employee.emnumber == x) return(root);
    i = root->employee.emnumber <= x;
    return search(root->child[i], x);
}

そして追加は今です:

BST *add(BST *root){
    BST *invalid = NULL;
    BST *temp = malloc (sizeof (BST) );
    temp->child[0] = temp->child[1] = temp->parent = NULL;

    printf("\n\tADD EMPLOYEE INFORMATION\n");
    printf("\nEnter Employee Number: ");
    scanf("%d", &(temp->employee.emnumber) );
    if(temp->employee.emnumber > 99999 || temp->employee.emnumber < 1)
        printf("\nInvalid Input!\n(Input only 5-digit number)\n\n");
    else{
        invalid = search(root,temp->employee.emnumber);
        if(invalid != NULL) printf("\nInvalid Input!\n(Already in the database)\n\n");
        else{
           /*The same codes here*/
        }
    }
}

問題は、「無効な入力」が発生したときにルートに戻ることにあると思います。私はroot=add(root)でadd()を呼び出すので、問題が発生した場合はnullなどを指します。それで、あなたは私が何をしなければならないと思いますか?

編集[最後]:問題は、実際には、「無効な入力」が発生した場合にadd()が返す内容にあります。root = add(root)を回避するためにBST *addをvoidaddに変更し、関数で必要な変更を行ったところ、機能するようになりました。回答ありがとうございますが、誰も正解していないと思うのでチェックマークを付けることができません。私は今それをfgets()で動かしています。

4

2 に答える 2

1

始めましょう:checknum()子に対してチェックして再帰する必要がある場合、何が返されますか?

または、同等に、-Wallすべての警告をアクティブにするコンパイラの同等のものを使用してコンパイルしましたか? どんな警告がありましたか?

于 2011-06-22T11:22:59.790 に答える
0

return関数の最後にa がありませんchecknum():

  int i = root->employee.emnumber <= num;
  return checknum(root->child[i], num);        //Added a return here
}

returnの再帰呼び出しがなければchecknum()効果がなく、最終的な戻り値はおそらくあなたが望むものではありません。警告がオンになっていると仮定すると、コンパイラはこれについて警告するはずです(通常、「すべてのパスが値を返すわけではありません」のようなものです)。

于 2011-06-22T13:11:28.583 に答える