0

こんにちは、スタックデータ構造プログラムに問題があります。配列のサイズ/配列の仮想サイズをループで呼び出すために定義すると、データを入力したりプッシュしたりすると、ユーザーが定義または指定したサイズが使い果たされるか、多少編集されているようです。

例:サイズに5を入力し、プッシュを選択してから2を追加しました。正常に動作しています。しかし、データを再度プッシュすることを選択した場合、データはサイズ変数に渡されます。何が起こっているのかわかりません...

#include <stdio.h>
#include <ctype.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#define p printf
#define s scanf

int top;
int ar[1];
int size;

main()
{
    void push();
    int opt, num;
    char cont[] = { 'y' };
    clrscr();

    p("Stacking Program");
    p("\n\nData Size: ");
    s("%d", &size);
    p("\n");

    while((cont[0] == 'y') || (cont[0] == 'Y'))
    {
        clrscr();
        p("Stacking Program");
        p("\n\nData Size: %d\n\n", size);
        p("MAIN MENU\n1. Pop\n2. Push\n3. Pick\n4. View\nChoose: ");
        s("%d", &opt);
        p("\n");

        switch(opt) {
            case 1:
                pop();
                break;
            case 2:
                if(top > size)
                {
                    p("You can't push more data");
                }
                else
                {
                    p("Enter data for Data[%d]: ", top);
                    s("%d", &num);
                    push(num);
                }
                break;
            case 3:
                pick();
                break;
            case 4:
                view();
                break;
            default:
                p("Your choice is not in the list.");
                break;
        }

        p("\n\nDo you want continue\(Y\/N\)?");
        s("%s", &cont[0]);
    }
}

pop()
{
    int a;
    if(top < 0)
    {
        p("Stack empty.");
        return 0;
    }
    else
    {
        a = ar[top];
        p("\(Data[%d] = %d\) removed.", top, a);
        top--;
    }
}
void push(int b)
{
    top++;
    ar[top] = b;
}
pick()
{
    if(top < 0)
    {
        p("Nothing to display.");
        return 0;
    }
    else
    {
        p("\(Data[%d] = %d\) is the last data.", top, ar[top]);
    }
}
view()
{
    int i;
    if(top < 0)
    {
        p("Nothing to display.");
        return 0;
    }
    else
    {
        for(i = 1; i < (top + 1); i++)
        {
            p("Data[%d] = %d\n", i, ar[i]);
        }
    }
}
4

2 に答える 2

0

ユーザーが入力したサイズを使用して、実行時に配列のサイズを定義する必要があります。それ以外の:

int top;
int ar[1];
int size;

..。

int top = -1;
int *ar = NULL;
int size = 0;

そして、ユーザーからサイズを取得した後:

   if ( size > 0 )
   {
      ar = malloc(size * sizeof(int));
      if ( ar == NULL )
      {
         printf("ERROR: malloc() failed\n");
         exit(2);
      }
   }
   else
   {
      printf("ERROR: size should be positive integer\n");
      exit(1);
   }


   ....
      p("\n\nDo you want continue(Y/N)?");
      s("%s", &cont[0]);
   }
   free(ar);


} // end of main

view()のforループは次のようになります。

 for(i = 0 ; i <= top ; i++)

また

case 2:
    if ( top == ( size - 1 ))
于 2012-09-27T23:14:13.327 に答える
0

配列のサイズを動的に変更したくない場合は、MAXSIZE要素を使用して配列を割り当てることもできます。MAXSIZEは「十分な大きさ」です。また、他のいくつかのコメント:

プログラムの先頭で、サイズ1の文字配列を宣言しました。

char cont[] = { 'y' };

しかし、後でscanf行で、これを使用しようとします。

s("%s", &cont[0]);

これにより、ユーザーが1文字だけ入力した場合でも、バッファーがオーバーフローします。これは、%sは、バッファーに少なくとも2バイトが使用可能であると想定しているためです。1つは文字用、もう1つは'\0'用です。考えられる修正:

char cont[] = { 'y', '\0' };
// ...
s("%1s", cont);

contは、&cont [0]の同じ、より一般的な言い方であることに注意してください。

もう1つの問題は、警告がオンになっている場合にコンパイラーがキャッチする可能性のある問題です。すべての関数は、言及される前にプロトタイプ化する必要があり、明示的な戻り型のない関数はint型で宣言する必要があります。また、関数をドロップオフさせないでください。明示的または暗黙的に値を宣言した場合でも、値を返します。また、'('および')'は文字列リテラルでエスケープする必要はありません。

これは、変更が記載された変更バージョンです。このシステムにconio.hがないため、clrscr()を再定義しました。

#include <stdio.h>
#include <ctype.h>
// #include <conio.h>
#define clrscr() printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n")
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

#define p printf
#define s scanf

#define MAXSIZE 500


// prototypes [Changed]
int pop();
void push(int b);
int pick();
int view();

int top;
int ar[MAXSIZE];
int size;

int main()
{
    int opt, num;
    char cont[] = { 'y', '\0' }; // [Changed]
    clrscr();
    p("Stacking Program\n\n");

    // keep asking until we get a valid size [Changed]
    for (;;)
    {
        p("Data Size: ");
        s("%d", &size);
        if (size > 0 && size < MAXSIZE)
            break;
        printf("Not a valid size!\n");
    }
    p("\n");

    while((cont[0] == 'y') || (cont[0] == 'Y'))
    {
        clrscr();
        p("Stacking Program");
        p("\n\nData Size: %d\n\n", size);
        p("MAIN MENU\n1. Pop\n2. Push\n3. Pick\n4. View\nChoose: ");
        s("%d", &opt);
        p("\n");

        switch(opt) {
            case 1:
                pop();
                break;
            case 2:
                if(top > size)
                {
                    p("You can't push more data");
                }
                else
                {
                    p("Enter data for Data[%d]: ", top);
                    s("%d", &num);
                    push(num);
                }
                break;
            case 3:
                pick();
                break;
            case 4:
                view();
                break;
            default:
                p("Your choice is not in the list.");
                break;
        }

        p("\n\nDo you want continue(Y/N)?");
        s("%1s", cont); // [Changed]
    }
    return 0;
}

int pop()
{
    int a;
    if(top == 0) // [Changed]
    {
        p("Stack empty.");
        return 0;
    }
    else
    {
        top--; // [Changed]
        a = ar[top];
        p("(Data[%d] = %d) removed.", top, a);
        return a; // [Changed]
    }
}

void push(int b)
{
    ar[top] = b;
    top++; // [Changed]
}

int pick()
{
    if(top == 0) // [Changed]
    {
        p("Nothing to display.");
        return 0;
    }
    else
    {
        p("(Data[%d] = %d) is the last data.", top, ar[top-1]); // [Changed]
        return -1; // [Changed]
    }
}

int view()
{
    int i;
    if(top < 0)
    {
        p("Nothing to display.");
        return 0;
    }
    else
    {
        for(i = 0; i < top; i++)  // [Changed]
        {
            p("Data[%d] = %d\n", i, ar[i]);
        }
        return -1;  // [Changed]
    }
}
于 2012-09-28T10:27:59.177 に答える