0

当我为案例输入数字时,我希望我的 do-while 循环不断重复。例如,如果我想在数组中插入一个元素,我会输入 1,然后我会输入我想要插入的元素和索引。然后它应该再次显示菜单,但由于某种原因,它只是打破了 do-while 循环?

#include <iostream>
using namespace std;

struct Array
{
    int *A;
    int size;
    int length;
};

void display(struct Array *arr)
{
    int i;
    printf("\nElements: ");
    for(i = 0; i < arr->length; i++)
        printf("%d ", arr->A[i]);
};

struct Array *mergeArrays(struct Array *array1, struct Array *array2)
{
    int i = 0;
    int j = 0;
    int k = 0;

    struct Array *array3;

    int length = array1->length + array2->length;
    array3 = new Array[length];

    while(i < array1->length && j < array2->length)
    {
        if(array1->A[i] < array2->A[j])
        {   
            array3->A[k++] = array1->A[i++];
        }
        else
        {
            array3->A[k++] = array2->A[j++];
        }
    }

    for(; i < array1->length; i++)
        array3->A[k++] = array1->A[i];
    for(; j < array2->length; j++)
        array3->A[k++] = array2->A[j];

    array3->length = length;

    return array3;
};

struct Array *Union(struct Array *array1, struct Array *array2)
{
    int i = 0;
    int j = 0;
    int k = 0;

    struct Array *array3;

    int length = array1->length + array2->length;
    array3 = new Array[length];

    while(i < array1->length && j < array2->length)
    {
        if(array1->A[i] < array2->A[j]) {   
            array3->A[k++] = array1->A[i++];
        }
        else if(array2->A[j] < array1->A[i]){
            array3->A[k++] = array2->A[j++];
        } else {
            array3->A[k++] = array1->A[i++];
            j++;
        }
    }

    for(; i < array1->length; i++)
        array3->A[k++] = array1->A[i];

    array3->length = k;
    array3->size = 10;

    return array3;
};

struct Array *Intersection(struct Array *array1, struct Array *array2)
{
    int i = 0;
    int j = 0;
    int k = 0;

    struct Array *array3;

    int length = array1->length + array2->length;
    array3 = new Array[length];

    while(i < array1->length && j < array2->length)
    {
        if(array1->A[i] < array2->A[j]) {
            i++;
        } else if(array2->A[j] < array1->A[i]) {
            j++;
        } else {
            array3->A[k++] = array1->A[i++];
            j++;
        }
    }

    array3->length = k;
    array3->size = 10;

    return array3;
};

struct Array *Difference(struct Array *array1, struct Array *array2)
{
    int i = 0;
    int j = 0;
    int k = 0;

    struct Array *array3;

    int length = array1->length + array2->length;
    array3 = new Array[length];

    while(i < array1->length && j < array2->length)
    {
        if(array1->A[i] < array2->A[j]) {   
            array3->A[k++] = array1->A[i++];
        }
        else if(array2->A[j] < array1->A[i]){
            j++;
        } else {
            i++;
            j++;
        }
    }

    for(; i < array1->length; i++)
        array3->A[k++] = array1->A[i];

    array3->length = k;
    array3->size = 10;

    return array3;
};

int Delete(struct Array *array1, int index)
{
    int x = 0;
    int i = 0;

    if(index >= 0 && index < array1->length)
    {
        x = array1->A[index];
        for(i = index; i < array1->length-1; i++)
            array1->A[i] = array1->A[i+1];
        array1->length--;
    }
    return x;
};

void Append(struct Array *array1, int value)
{  
    if(array1->length < array1->size)
        array1->A[array1->length++] = value;
};

void Insert(struct Array *array1, int index, int element)
{   
    int i;
    if(index >= 0 && index <= array1->length)
    {
        for(i = array1->length; i > index; i--)
            array1->A[i] = array1->A[i-1];

        array1->A[index] = element;
        array1->length++;
        
    }
}

bool Search(struct Array *array1, int element)
{
    for(size_t i{0}; i < array1->length; i++) {
        if(array1->A[i] == element)
            return true;
    }
    return false;
};

void Sum(struct Array array1)
{
    int arraySum = 0;

    for(int i{0}; i < array1.length; i++)
    {
        arraySum+=array1.A[i];
    }

    cout << arraySum << endl;
}


int main()
{
    int index;
    int x;
    int ch;

    struct Array array1;
    printf("Enter Size Of Array: ");
    scanf("%d", &array1.size);
    array1.A=(int *)malloc(array1.size*sizeof(int));

    do
    {
    printf("Display Menu\n");
    printf("1. Insert\n");
    printf("2. Delete\n");
    printf("3. Search\n");
    printf("4. Sum\n");
    printf("5. Display\n");
    printf("6. Exit \n");

    printf("Enter Your Choice: ");
    scanf("%d",&ch);

    switch(ch)
    {
        case 1: printf("Enter Element First And Then Index: ");
            scanf("%d%d", &x, &index);
            Insert(&array1,index, x);
            break;

        case 2: printf("Enter Index To Be Deleted: ");
            scanf("%d",&index);
            x = Delete(&array1, index);
            printf("Deleted Element is %d|n", x);
            break;

        case 3: printf("Enter Element To Be Searched: ");
            scanf("%d", x);
            x = Search(&array1, x);
            break;

        case 4: printf("Array Sum: ");
            Sum(array1);
            break;
        
        case 5: display(&array1);
    }
    } while(ch < 6);
      return 0;
}
4

1 回答 1

0

首先,不要将输入与std::cin和 C混合scanf(),这只是灾难的根源。选择 C++iosteam或 C stdio.h,但不能同时选择两者。无论您选择哪种方式,您都可以通过检查输入函数的返回来验证每个输入。在 C++ 中,您正在检查流状态,在 C 中,您正在验证函数返回。如果 C 和 C++ 都发生故障,则在遇到错误时停止从输入流中提取字符。在尝试下一个输入之前,由您来处理错误并从输入流中提取有问题的字符(在 C++ 中,您还必须是流状态).clear()

接受用户输入

如果您正在使用scanf(),您将执行以下操作:

        if (scanf ("%d",&ch) != 1) {    /* validate EVERY input */
            fputs ("  error: invalid integer input.\n", stderr);
            empty_stdin();              /* on invalid input, you must empty stdin */
            continue;
        }

辅助函数empty_stdin()写为:

void empty_stdin (void)
{
    int c = getchar();
    
    while (c != '\n' && c != EOF)
        c = getchar();
}

注意:这适用于程序中的每个输入...如果您使用的是 C 输入,请考虑将所有输入读入一个固定数组,fgets()并使用 解析数组中所需的值sscanf()。这消除了在在匹配失败的情况下输入流。)

在 C++ 中使用iostream,你会这样做:

        if (!(std::cin >> ch)) {    /* validate EVERY input, handle error */
            std::cerr << "  error: invalid integer input.\n";
            std::cin.clear();   /* clear failbit steam state */
            /* empty offendinding characters from stdin */
            std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
            continue;
        }

std::cin.ignore()提供了用于清除违规字符的位置,其中提供std::numeric_limitslimits.

新的还是 malloc()?

malloc()在 C++ 中使用必须非常小心。例如,在 C++ 中分配stuctwithmalloc()将失败。malloc()对对象构造函数一无所知,所以如果你在 C++ 中为struct Arraywith分配malloc(),你最终会得到一个部分构造的对象。在 C++ 中使用newanddelete而不是在分配对象时使用malloc()and 。free()你的老师不应该鼓励malloc()在 C++ 中使用。

array1.A您可以有效分配with的唯一原因malloc()A一个普通的旧指针int。没有与为 a 分配存储相关的构造函数int,因此在这种情况下使用是允许的(但不明智)malloc()。然后问题就变成了记住您分配的malloc()内容和分配的内容new,因为free()delete不可互换。

你做 { ... } while(); 环形

从表面上看,没有任何理由你的 do 循环不会做你所期望的——只要每个输入都是完美的。然而,一个错误的字符或一个手指从钥匙上滑落,你的整个易碎卡片就会崩溃。如果用户不小心伸手去触碰会发生'4'什么'r'?(真的很糟糕)。default:如果您退出任何大于5(您不能)的有效整数,您如何处理通常处理错误的情况。

通过控制循环,while (ch < 6);您可以消除默认情况下可以提供的所有错误处理。如果要在 上退出6,请创建一个case 6:并使用它来控制退出循环。然后你可以循环while (true);do { ... } while (true);

无论您使用 Cstdio.h还是 C++ iostream,都没有理由为了显示菜单而进行八个独立的函数调用。您需要拨打fputs()或 至std::cout。为什么?在编译期间,编译器会将所有相邻的字符串文字连接成一个字符串。因此,您可以将菜单显示为:

        fputs ("\nDisplay Menu\n"
               "  1. Insert\n"
               "  2. Delete\n"
               "  3. Search\n"
               "  4. Sum\n"
               "  5. Display\n"
               "  6. Exit \n\n"
               "Enter Your Choice: ", stdout);

或者

        std::cout << "\nDisplay Menu\n"
                     "  1. Insert\n"
                     "  2. Delete\n"
                     "  3. Search\n"
                     "  4. Sum\n"
                     "  5. Display\n"
                     "  6. Exit \n\n"
                     "Enter Your Choice: ";

(它也更容易阅读......)

C++ 使用 C malloc() 和 stdio.h

考虑到这些修复,并去除所有未使用的函数,您可以使用和I/O 函数编写 C++ 代码,您可以执行以下操作struct Arraymalloc()stdio.h

#include <stdio.h>
#include <stdlib.h>

struct Array {
    int *A,
        size,
        length;
};

void display (struct Array *arr)
{
    int i;
    
    fputs ("\nElements: ", stdout);
    
    for(i = 0; i < arr->length; i++)
        printf (i ? " %d" : "%d", arr->A[i]);
    putchar ('\n');                             /* tidy up with newline */
}


int Delete (struct Array *array1, int index)
{
    int x = 0;
    int i = 0;

    if (index >= 0 && index < array1->length)
    {
        x = array1->A[index];
        for(i = index; i < array1->length-1; i++)
            array1->A[i] = array1->A[i+1];
        array1->length--;
    }
    
    return x;
}

void Insert(struct Array *array1, int index, int element)
{   
    int i;
    if(index >= 0 && index <= array1->length)
    {
        for(i = array1->length; i > index; i--)
            array1->A[i] = array1->A[i-1];

        array1->A[index] = element;
        array1->length++;
        
    }
}

bool Search(struct Array *array1, int element)
{
    for(int i = 0; i < array1->length; i++) {
        if(array1->A[i] == element)
            return true;
    }
    return false;
}

void Sum(struct Array array1)
{
    int arraySum = 0;

    for(int i = 0; i < array1.length; i++)
    {
        arraySum+=array1.A[i];
    }

    printf ("%d\n", arraySum);
}

void empty_stdin (void)
{
    int c = getchar();
    
    while (c != '\n' && c != EOF)
        c = getchar();
}

int main (void)
{
    int index,
        x,
        ch;
    struct Array array1;
    
    fputs ("Enter Size Of Array: ", stdout);
    if (scanf("%d", &array1.size) != 1) {                   /* validate EVERY input */
        fputs ("error: invalid integer input.\n", stderr);
        return 1;
    }
    
    /* you cannot MIX malloc & new, you do not cast malloc in C, you do in C++ */
    array1.A = (int *)malloc(array1.size*sizeof(int));
    
    if (!array1.A) {    /* validate EVERY allocation using malloc */
        perror ("malloc-array1.A");
        return 1;
    }

    do
    {
        fputs ("\nDisplay Menu\n"
               "  1. Insert\n"
               "  2. Delete\n"
               "  3. Search\n"
               "  4. Sum\n"
               "  5. Display\n"
               "  6. Exit \n\n"
               "Enter Your Choice: ", stdout);
        
        if (scanf ("%d",&ch) != 1) {    /* validate EVERY input */
            fputs ("  error: invalid integer input.\n", stderr);
            empty_stdin();              /* on invalid input, you must empty stdin */
            continue;
        }
    
        switch(ch)
        {
            case 1: fputs ("Enter Element First And Then Index: ", stdout);
                if (scanf ("%d %d", &x, &index) != 2) {
                    fputs ("  error: invalid element or index.\n", stderr);
                    empty_stdin();
                    continue;
                }
                Insert (&array1, index, x);
                break;
    
            case 2: fputs ("Enter Index To Be Deleted: ", stdout);
                if (scanf ("%d", &index) != 1) {
                    fputs ("  error: invalid index to delete.\n", stderr);
                    empty_stdin();
                    continue;
                }
                x = Delete (&array1, index);
                printf ("Deleted Element is %d\n", x);
                break;
    
            case 3: printf ("Enter Element To Be Searched: ");
                if (scanf ("%d", &x) != 1) {
                    fputs ("  error: invalid search element.\n", stderr);
                    empty_stdin();
                    continue;
                }
                if (Search (&array1, x)) 
                    puts ("element found.");
                else
                    puts ("element not found.");
                break;
    
            case 4: fputs ("Array Sum: ", stdout);
                Sum (array1);
                break;
            
            case 5: display (&array1);
                break;
            
            case 6: puts ("\nend program");
                return 0;
                break;
            /* always provide a default case to catch invalid case requests */
            default: fputs ("  error: invalid selection.\n", stderr);
                break;
        }
    } while (1);
    
    free (array1.A);        /* don't forget to free the memory you allocate */
    
    return 0;
}

您的代码使用 C++ 和 std::vector<int>

您的老师没有教您使用C++stdio.hmalloc()C++。是的,那是 90 年代初的 C++,当时 C++ 是 C 的超集,但今天,C++ 本身就是一门语言,不需要依赖它的大部分 C 基础。没有理由使用 a和 a的struct Array指针,std::vector提供了所有这些功能(以及更多)。int*sizelength

使用std::vector<int>替换您的struct Array,您可以简化和改进您的程序,如下所示:

#include <iostream>
#include <string>
#include <vector>
#include <limits>

void display (std::vector<int>& arr)
{
    std::cout << "\nElements: ";
    
    for (int a : arr)
        std::cout << " " << a;
    std::cout.put ('\n');
}

void Delete (std::vector<int>& arr, size_t index)
{
    arr.erase (arr.begin() + index);
}

void Insert (std::vector<int>& arr, int element, size_t index)
{   
    if (index <= arr.size()) {
        arr.insert (arr.begin() + index, element);
    }
    else {
        std::cerr << "  error: index out of range, appending element.\n";
        arr.push_back (element);
    }
}

bool Search (std::vector<int>& arr, int element)
{
    for (int a : arr)
        if (a == element)
            return true;
    
    return false;
}

void Sum (std::vector<int>& arr)
{
    int arraySum = 0;

    for (int a : arr)
    {
        arraySum += a;
    }

    std::cout << arraySum << '\n';
}

int main (void)
{
    int ch = 0,
        x = 0;
    size_t ndx = 0;
    std::vector<int> array1{};
    
    do
    {
        std::cout << "\nDisplay Menu\n"
                     "  1. Insert\n"
                     "  2. Delete\n"
                     "  3. Search\n"
                     "  4. Sum\n"
                     "  5. Display\n"
                     "  6. Exit \n\n"
                     "Enter Your Choice: ";
        
        if (!(std::cin >> ch)) {    /* validate EVERY input, handle error */
            std::cerr << "  error: invalid integer input.\n";
            std::cin.clear();   /* clear failbit steam state */
            /* empty offendinding characters from stdin */
            std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
            continue;
        }
    
        switch (ch)
        {
            case 1: std::cout << "Enter Element and index: ";
                /* validate EVERY input, handle error */
                if (!(std::cin >> x >> ndx)) {
                    std::cerr << "  error: invalid input for insert.\n";
                    std::cin.clear();   /* clear failbit steam state */
                    /* empty offendinding characters from stdin */
                    std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
                    continue;
                }
                Insert (array1, x, ndx);
                break;
    
            case 2: std::cout << "Enter Index To Be Deleted: ";
                if (!(std::cin >> ndx)) {  /* validate EVERY input, handle error */
                    std::cerr << "  error: invalid index input to delete.\n";
                    std::cin.clear();   /* clear failbit steam state */
                    /* empty offendinding characters from stdin */
                    std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
                    continue;
                }
                if (ndx < array1.size()) {
                    x = array1[ndx];                /* index < size */
                    std::cout << "Deleted Element is " << x << '\n';
                    Delete (array1, ndx);
                }
                else {  /* ndx not a valid index */
                    std::cerr << "  error: invalid index.\n";
                }
                break;
    
            case 3: std::cout << "Enter Element To Be Searched: ";
                if (!(std::cin >> x)) {    /* validate EVERY input, handle error */
                    std::cerr << "  error: invalid integer input to search.\n";
                    std::cin.clear();   /* clear failbit steam state */
                    /* empty offendinding characters from stdin */
                    std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
                    continue;
                }
                if (Search (array1, x)) 
                    std::cout << "element found.\n";
                else
                    std::cout << "element not found.\n";
                break;
    
            case 4: std::cout << "Array Sum: ";
                Sum (array1);
                break;
            
            case 5: display (array1);
                break;
            
            case 6: std::cout << "\nend program\n";
                return 0;
                break;
            /* always provide a default case to catch invalid case requests */
            default: std::cerr << "  error: invalid selection.\n";
                break;
        }
    } while (true);
}

评论中包含并指出了一些其他更改,但基本上,除了了解过去的工作方式之外,您还希望将 C++ 学习集中在今天如何使用 C++。否则,学习 C 将涵盖您在问题中发布的全部内容。

如果您还有其他问题,请仔细查看并告诉我。

于 2021-03-03T02:18:38.157 回答