簡體   English   中英

掃描未知數量的輸入並在 C 中打印條形圖

[英]Scan unknown number of inputs and print bar chart in C

我很茫然。 附上一張我已經研究了至少 6 個小時但無法弄清楚的問題的圖片。
總結一下問題是什么——只從一行讀取整數輸入。 該行中的第一個數字指定將跟隨多少個數字(從 1 到 40 個數字)。 然后使用以下數字並在最底部創建條形圖,其中“*”對應於輸入的數字。 就像我說的,閱讀附圖,它會更有意義。 我可以讓程序運行,但前提是我讓用戶在不同的行中輸入數字。 我也知道如何使用數組來做到這一點。 但是我們不允許使用數組。 只能使用 for 循環、while 循環的任何變體、嵌套循環、if 語句、pow 函數、int float 和 double、switch 語句、getchar()、scanf() 和邏輯運算符。 我發布了我的代碼,但它沒用。 任何幫助將不勝感激。

問題的圖片

//Homework 4 - Question 3

//main.c


//indicates preprocessor
#include <stdio.h>


//being function main
int main(void){


    //define variables
    int barnum, counter = 1, counter2 = 0, length = 0;


    //prompt for number of bars user wants to input
    printf("--------------------Bar Chart Calculator--------------------\n");
    printf("Enter integers from 1 to 40 for questions below.\n");
    printf("------------------------------------------------------------\n\n");
    printf("Enter the number of bars wanted in chart: ");
    scanf("%d", &barnum);

    printf("Enter the length of each bar, pressing enter after each entry.\n");
    printf("---------Begin entering integers below this line-------------\n");



    //while loop to repeat for specified number of bars
    while (counter <= barnum){
        length = 0;
        counter2 = 0;
        scanf("%d", &length);

        //while loop to print individual * in a single line
        while (counter2 < length) {
            printf("*");
            counter2++;  //increments counter
        }//end counter 2 while loop

        printf("(%d)\n", length);
        counter++;  //increments counter

    }  //end counter while loop


    return 0;  //indicates program ended successfully

}  //end function main

stdin輸入流通常在 C 中緩沖,因此在用戶按下Enter后流中的任何輸入都可用於scanf()直到該輸入用完為止。 在第一次調用scanf() ,您將擁有要跟隨的輸入項的數量。 然后循環可以執行對scanf()進一步調用,直到沒有更多的輸入可供讀取。

請注意,更健壯的代碼應該檢查調用scanf()返回的值,以防止輸入格式錯誤和罕見的輸入失敗事件。

#include <stdio.h>

int main(void)
{
    int num_values;
    scanf("%d", &num_values);

    for (int i = 0; i < num_values; i++) {
        int val;
        scanf("%d", &val);
        printf("Value %d: %d\n", i, val);
    }

    return 0;
}

示例程序交互:

>$ ./a.out 
6 3 1 4 1 5 9
Value 0: 3
Value 1: 1
Value 2: 4
Value 3: 1
Value 4: 5
Value 5: 9

潛在的陷阱

由於輸入一直保留在輸入流中,直到它被某個函數調用讀取,因此對scanf()后續調用可能會選擇以前的、未讀的輸入值,從而導致意外(可能未定義)的行為。

例如,如果條形圖程序在顯示第一個數據集的結果后循環允許用戶輸入另一個數據集,則可能會出現問題。 假設用戶輸入的數據比第一個數字所指示的多: 3 1 2 3 4 顯示條形圖后, 4仍將保留在輸入流中。 隨后對scanf()調用將選擇這個4 ,而不是代碼期望的任何輸入。 嘗試在下面的代碼中注釋掉對clear_stream()的調用,看看當輸入行包含的項目多於預期時會發生什么。

慣用的解決方案是通過使用getchar()讀取輸入流中的所有剩余字符來清除輸入流:

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

變量c需要是int而不是char以確保getchar()返回的值(它是一個int並且可能是EOF ,通常是-1 )可以保存在c 循環讀取並丟棄輸入流中的字符,直到到達換行符或EOF getchar()函數在極少數發生錯誤的情況下返回EOF ,但用戶也可能輸入EOF ,因此必須顯式測試此值以避免可能的無限循環。

為避免格式錯誤的輸入出現更多問題,請檢查調用scanf()返回的值。 此函數將調用期間成功分配的次數作為int值返回(或可能返回EOF )。 如果用戶為初始值輸入了一個字母而不是數字來表示數據集中值的數量,則num_values不會存儲任何值(因此num_values的值保持不確定)。 當代碼稍后嘗試使用num_values時,這會導致未定義的行為。 通過檢查scanf()是否按預期返回值1 ,可以避免這種情況。

下面的代碼允許用戶輸入一行數據,前面是數據項的數量。 如果用戶為項目數輸入-1 (或任何小於 1 的值,或非數字輸入),則程序退出。 此外,如果用戶在數據項中輸入了非數字輸入,則不會顯示該輸入項的圖形。

#include <stdio.h>

void clear_stream(void);
void print_bar(int n);

int main(void)
{
    char *prompt = "Enter the number of values to graph, followed by the values"
                   " (-1 to exit)";
    int num_values;
    puts(prompt);
    int ret_scanf = scanf("%d", &num_values);

    while (ret_scanf == 1 && num_values > 0) {
        for (int i = 0; i < num_values; i++) {
            int val;
            /* print bar if a number was entered */
            if (scanf("%d", &val) == 1) {
                print_bar(val);
            }
        }
        putchar('\n');
        puts(prompt);
        clear_stream();                        // try commenting out this line
        ret_scanf = scanf("%d", &num_values);
    }

    return 0;
}

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

void print_bar(int n)
{
    for (int i = 0; i < n; i++) {
        putchar('*');
    }
    putchar('\n');
}

示例程序交互:

>$ ./a.out 
Enter the number of values to graph, followed by the values (-1 to exit)
6 3 1 4 1 5 9
***
*
****
*
*****
*********

Enter the number of values to graph, followed by the values (-1 to exit)
-1

我認為這會奏效。 您不需要創建 41 個變量。 您可以輸入任意數量的值,但如果scanf語句只接受一個值,它將采用第一個值,其余值將保留在隊列中。 因此,下次控件遇到scanf語句時,它會采用您之前輸入的第二個值。

在您的問題中,您必須首先輸入后面的值的數量。 您可以使用它來了解在循環中運行 scanf 語句的次數。 我在這里使用了if語句和goto的組合。

#include <stdio.h>

int main()
{
int i, j, k, l=1;

/* Here variable 'i' stores the first number entered */

printf("Enter intergers from 1 to 40 where first number indicates how many 
numbers follow: ");
scanf("%d", &i);



a : scanf("%d", &j);

for(k=1 ; k<=j; k++)
{
    printf("*");
}

printf("\n");
l++;
if(l<=i)
goto a;

return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM