2016-10-22 23 views
1

scanf関数を使用して、ユーザーの入力上のさまざまな数値の未知の量を読み取る必要があります。これは、単純に、さまざまな整数の数が、可能な限り多くの数値を送信することによってユーザーによって決定されることを意味します。コードを次のように述べたように、私は、(私が持っている)に直接数字を読むことに注意してください:問題:C不明なサイズの整数配列の宣言

int main(void) 
{ 
    int numbers[]; 
    int error = 0; 

    int i = 0; 
    while(scanf("%i", &numbers[i++]) == 1); 

    for(int i = 0; i < sizeof(numbers) - 1; ++i) { 
     if(numbers[i] < -10000 || numbers[i] > 10000) 
     { 
      printf("%i%s", numbers[i], ", "); 
     } 
     else 
     { 
      printf("%s", "\b\b\nError: Error: Vstup je mimo interval!\n"); 
      // Means "Input is out of range!". 
      // We have to write exact output to terminal as stated in HW. 
      i = sizeof(numbers); 
      error = 1; 
     } 
    } 

    ... 
} 

int errorは実際にはブール値ですが、私はブールライブラリを実装するために怠惰だので、私は整数としてそれを定義します。 D

しかし、問題は他のところです。コンパイラが私にエラーを投げます:

Cプログラムは配列の割り当て可能なサイズを知る必要があります。しかし、それはして問題を解決していません

C - Declaring an array with an undefined value

:私はすでに他の人が、配列のサイズの問題を探している間、私が実装する必要があると基本を見つけるためにそこに共有している、私はこの質問を見つけたいくつかのコードに見えました未知の量の数を直接入力するための未知の配列サイズ。私は解決する必要があるところがどこにもないことを発見しました。 、数字の統計のために使用されるすべてのforループと同じ

main.c:50:23: error: iteration 999u invokes undefined behavior [-Werror=aggressive-loop-optimizations] 
      if(numbers[j] > 0) 
        ^
main.c:48:9: note: containing loop 
     for(int j = 0; j < sizeof(numbers); ++j) 
     ^

(合計、最大値、最小値、オッズは、追いついた:私は、999の番号まで保持するために、配列の最大サイズを定義しようとしたが、その後、コンパイラは私にこの例外をスローしますポジティブ、ネガティブ、パーセンテージおよび平均)。つまり、配列のサイズは厳密に999で、残りの数字は0になります。私はmalloc機能を見つけたが、その使用法を理解していない:(

+0

mallocの場合:配列を 'int * arr'として宣言してから、使用する前に' arr =(int *)malloc(n * sizeof(int)); '、ここでnは必要なサイズで、関数の最後に' free(arr); 'を呼び出す必要があります。 –

+0

実際の問題について:サイズ999の配列には0から998までのインデックスが有効です。 –

+0

さらに、 'typedef enum {false、true} bool;'はブール値を実装するのに十分な*です。 –

答えて

1

「私はscanf関数を使用して、ユーザの入力に様々な数の未知の量を読んでする必要があります。」貧しい設計目標である。

どれでも外部結合したことなく、入力への入力のいずれか量をインターフェース可能プログラムは、ハッカーが悪用である。

寛大に

ロバストコード限界ユーザ入力が、健全な入力量グッドコードが定数としてその上限をコードするか、またはマクロ

scanf()を使用すると、ユーザー入力を読み取るのに最適なツールではありません。
fgets()を読んで、をお読みください。 (ここでは示されていない。)

#include <stdio.h> 
#include <ctype.h> 

// find the next character without consuming it. 
int peek_ch(void) { 
    unsigned char ch; 
    if (scanf("%c", &ch) == 1) { 
    ungetc(ch, stdin); 
    return ch; 
    } 
    return EOF; 
} 

#define INPUT_N 1000 
void foo(void) { 
    int input[INPUT_N]; 
    size_t n = 0; 

    // Read 1 _line_ of input using `scanf("%d", ....)` to read one `int` at a time 
    for (n = 0; n < INPUT_N; n++) { 
    int ch; 
    while (((ch = peek_ch()) != '\n') && isspace(ch)) 
     ; 
    // %d consume leading white-space including \n, hence the above code to find it. 
    if (scanf("%d", &input[n]) != 1) { 
     break; 
    } 
    } 

    // TBD: Add code to handle case when n == N 

    for (size_t i = 0; i < n; i++) { 
    printf("%zu: %d\n", i, input[i]); 
    } 
} 
0

コメントにあなたの説明に基づいて、あなたはmallocで動的にメモリを割り当てるとrealloc、必要に応じてそれを拡張する必要があるとしています。ここで

は例の基本骨格だ:

#define INITIAL_SIZE 1024 

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

int main(void) 
{ 
    size_t arraySize = 0; 
    size_t i = 0; 

    // initially allocate numbers array 
    int *numbers = malloc(sizeof *numbers * INITIAL_SIZE); 
    if (!numbers) 
    { 
    fprintf(stderr, "Error allocating memory...exiting\n"); 
    exit(EXIT_FAILURE); 
    } 

    arraySize = INITIAL_SIZE; 
    int input; 
    while (scanf("%d", &input) == 1) 
    { 
    if (i == arraySize) 
    { 
     // double the size of the numbers array 
     int *tmp = realloc(numbers, sizeof *numbers * (2 * arraySize)); 
     if (!tmp) 
     { 
     fprintf(stderr, "Could not extend array size...no more inputs allowed\n"); 
     break; 
     } 
     numbers = tmp; 
     arraySize *= 2; 
    } 
    numbers[i++] = input; 
    } 

    // process numbers 
    ... 
    // clean up after ourselves 
    free(numbers); 
0

は、私は本当にそれを感謝し、あなたの助けありがとうございました。それは私を助けましたが、私が本当に必要としたのはその解決策ではありませんでしたが、少し異なりました。上記のコメントに記載されているように、私は宿題の入力と出力の要件を満たす必要がありました。私は私の担当者に連絡し、整数配列を取り除き、最初の数字リストの出力とすべての計算の進行をwhileループ内に囲むように提案しました。すべての最終出力でエラーが発生しなかった場合は、パーセンテージおよび平均合計の最終計算が条件テストに包まれます。しかし、これは本当に私がここで大いに役立ったので、解答としてマークされることはありません。しかし、私は非常に論理的であり、バッファオーバーフローによるマルウェアの悪用からどのプログラムも保護されるべきであるので、私はchuxの回答としてマークしました。もう一度お手伝いいただき、ありがとうございます。