For循环似乎变得无限

时间:2018-11-28 21:06:34

标签: c

#include <stdio.h>

// DEFINITION FOR THE PRICES. CHANGE/REMOVE if needed. Currently can be used for testing
#define pepsi 2.00
#define l_tea 1.50


// Menu function prototype for testing
// TODO: Replace with actual menu fucntion
void menu();
void inquire();
void calculate_price();
void order();

float total_price;
float price_per[3];

// Required for the Inquire function. **total_menu** can be moved inside function. Keep variable **choice** as is. DO NOT REMOVE.
// TODO: Change **total_menu** variable value to ACTUAL value
int choice[3] = {0,0,0};
int total_menu = 2; // <<<<<<<<<<< CHANGE

int main()
{
    inquire();
    order();

    return 0;
}

void inquire()
{
    char cont;

    // Start by giving instructions
    printf("Max 3 drinks. Input in NUMBER.\nChoose your drink(s):\n");

    // Implementation of menu function. Change name as seen fit.
    menu();

    for (int i = 0; i + 1 <= 3; i++)
    {
        // Ask for response
ask:
        printf("\n\n >>> ");
        scanf("%d", &choice[i]);

        // Check if in menu
        if ((int)choice[i] > total_menu)
        {
            printf("\nNot in menu. Please choose again!");
            goto ask;
        }
        printf("%d", i);
        // Ask if user wants to continue
        // Y for Yes, N for No.
        if (i + 1 < 3)
        {
            printf("\nDo you want to continue? (y/n) >> ");
            scanf("%s", &cont);

            switch (cont)
            {
                case 'y':
                    printf("\nChoose your drink %d: ", i + 2);
                    break;
                case 'n':
                    i = 4;
                    break;
                default:
                    printf("\nChoose your drink %d: ", i + 2);
            }
        }
    }

    // Testing array implementation. Delete before final program
    for (int i = 0; i + 1 <= 3; i++)
        printf("\n%d) %d", i+1, choice[i]);
}

// Menu definition FOR TESTING. Replace with actual menu function
// TODO: REPLACE with actual MENU FUNCTION
void menu()
{
    printf("1) Pepsi \t RM%.2f\n", pepsi);
    printf("2) Lemon Tea \t RM%.2f", l_tea);
}

// Calculate price FOR TESTING. Replace with actual calculate function
// TODO: REPLACE with actual CALCULATE FUNCTION
void calculate_price()
{
    total_price = 0.00;

    for (int i = 0; i <= 2; i++)
    {
        switch(choice[i])
        {
            // CASE BASED ON MENU
            case 1:
                price_per[i] = pepsi;
                total_price += pepsi;
                break;
            case 2:
                price_per[i] = l_tea;
                total_price += l_tea;
                break;
            default:
                total_price += 0;
                break;
        }
    }

}

void order()
{
    char cont;

    calculate_price();

    printf("\n\nTotal price -> RM%.2f:\n", total_price);

    for (int i = 0; i < 3; i++)
        printf("\tItem %d -> RM%f\n", choice[i], price_per[i]);

    printf("\nInsert Money? (y/n)");
    scanf(">> %s <<", cont);

    // No more testing needed.....
}

使用上面的代码,如果我键入“ y”一次,我的inquire函数中的for循环似乎会陷入无限循环。脱离的唯一方法是键入“ n”或退出程序。我花了更多的时间在此承认。我确实有它的工作版本,但我可能干预了导致此的事情。

我需要一些帮助。

2 个答案:

答案 0 :(得分:2)

char cont;
...
scanf("%s", &cont);

%s scanf修饰符scanf用于以空字符结尾的字符数组。您将scanf函数的第二个参数指定为仅一个字符的内存指针。我极力劝阻使用scanf扫描任意长度的用户输入,因为在您的情况下很容易导致堆栈溢出和超出数组访问范围。 scanf只是在地址(&cont)+1(&cont)+2等处写入内存,从而导致发生未定义的行为。这就是为什么总是%s scanf修饰符内指定字符串的长度。因此,您可以这样做:

char cont[512];
scanf"%511s", cont);

如果您打算扫描多达511个字符(而不是512,字符串以null终止),则需要从用户那里再输入一个字符,“ \ 0”即511)。 您可以这样做:

char cont;
scanf(" %c", &conf);

如果您打算扫描用户忽略前导空白字符输入的单个字符。

最好阅读scanf修饰符%s%c的文档,例如可以在cppreference上找到文档。而且永远不要在%s中输入scanf,总是输入%<number>s

答案 1 :(得分:-1)

@ user1930693。显然您在错误地扫描(读取)用户输入来决定是否继续。您可以通过scanf("%s", cont)来更改scanf(">>%s<<", cont)scanf("%c", &cont),使其与初始声明contchar cont)相匹配