2016-11-27 19 views
3

我一直在閱讀關於如何在事先不知道它的大小時如何聲明一個數組。據我所知,實現它的方法是爲用戶輸入的數組分配一些內存,然後根據需要重新分配或釋放內存。對於字符數組,我做了這種方式:如何允許用戶輸入沒有初始大小的數組?

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

int main() 
{ 
    //allocation of memory 
    char *a = malloc(200 * sizeof(char)); 

    //allow user input 
    fgets(a, 200, stdin); 

    int i = 0; 

    //find the length of the array 
    int lstring = strlen(a); 

    printf("%d", lstring-1); 

    free(a); 

    return 0; 
} 

在這裏,用戶不輸入字符數組的實際大小,但它可以通過查看結束的位置是已知的字符串字符。

在另一方面,對於整數數組我有這樣的:

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

int main() 
{ 
    //allocation of memory 
    int *b = malloc(200 * sizeof(int)); 

    b[0] = 2; 
    b[1] = 76; 
    b[2] = 123; 

    printf("%d", b[0]); 

    free(b); 

    return 0; 
} 

我的問題是,我怎麼能允許用戶輸入整數?

我想到的第一件事是創建一個for循環與scanf(),但是這是行不通的,除非允許用戶首先輸入數組的大小。有沒有一種方法(相當於或不是一個字符數組注意到的)這樣做而不讓用戶明確輸入大小?

+0

@WeatherVane Ups!我的意思是'int * b = malloc(200 * sizeof(int));' – Jazz

+2

請看看使用'realloc'來擴展數組。 –

+2

忽略一秒鐘的代碼,您希望從用戶的角度來看它的工作方式?他們是否希望在同一行輸入所有數字?還是有某種「我完成了」的指標,他們應該鍵入?也許Ctrl-D/Ctrl-Z發信號結束文件? –

回答

2

是的,你可以使用realloc()這一點。一個常見的方法是創建一個結構體,它將代表你的數組,可以是可擴展的。該結構可以是這樣的:

typedef struct 
{ 
    int allocated; // Here you can save how many elements you have allocated space for 
    int used; // Here is how many elements are in the array 
    int * array; // here is pointer to the array 

} Array; 

那麼你應該創建一個函數,將初始化Array結構:

void initArray(Array * a) 
{ 
    a->allocated = INIT_SIZE; 
    a->used = 0; 
    a->array = malloc(INIT_SIZE * sizeof(int)); 
} 

INIT_SIZE內容現在數組初始化,您已經分配的內存。現在是最重要的部分 - 實際上增加了元素。您還可以創建一個功能是:

bool insertEl(Array * a, int el) 
{ 
    if(a->used == a->allocated) //If there is no more space, then we need to realloc 
    { 
     int * temp = realloc(a->array, 2 * a->allocated * sizeof(int)); 
     if(!temp) // Just check if realloc succeeded 
     { 
      printf("Reallocation failed!\n"); 
      return false; 
     } 
     a->array = temp; 
     a->allocated *= 2; 
    } 

    a->array[a->used] = el; 
    a->used++; 

    return true; 
} 

經重新分配是相當昂貴的操作,這是很好的想法增加分配的要素不僅僅是某個常數的人數多。我通常加倍空間。既然你使用malloc()realloc()分配內存,你應該free()它一旦你用它做:

void freeArray(Array * a) 
{ 
    free(a->array); 
    a->array = NULL; 
    a->allocated = 0; 
    a-> used = 0; 
} 

一旦你有一個陣列結構這樣,你可以在循環運行scanf(),直到有一個EOF ,並在每個循環中,你輸入scanf()並用insertEl()函數將它添加到數組中。

3

是來到我的腦海裏的第一件事是創建一個for循環與scanf(),但這是行不通的,除非一個允許用戶先輸入數組的大小。有沒有一種方法(相當於或不是一個字符數組注意到的)這樣做而不讓用戶明確輸入大小?

你是在正確的軌道上...... 使用一個特殊的/標誌值,要知道用戶的例如這裏我用-1表示用戶的條目的結束條目結束

//allocating memory 
int *b = malloc(200 * sizeof *b); 

//notify the user with a message: 
printf("enter -1 to stop entry\n"); 

//loop to scan user entries 
for(int i = 0; i < 200; i++){ 
    //scanning user's input 
    scanf("%d", &b[i]); 

    //break when user enters -1 
    if(b[i] == -1){ 
     break; 
    } 
} 

此外,您可以使用-1,因爲您會使用作爲字符串來標記其結尾。例如:

int length = 0; //variable to know length of array 

//printing all the values of int array and knowing its length: 
for(int i = 0; b[i] != -1; i++){ 
    //for printing array elements 
    printf("%d ", b[i]); 

    //to know the length 
    length++; 
} 

如果用戶有什麼比輸入整數預期數量多嗎?

那麼你可以使用每次點擊最大值

時間例如realloc和雙數組的大小:

int max_entry = 100; //instead you can initialise max_entry by taking user's input 

//allocating memory 
int *b = malloc(max_entry * sizeof *b); 

//notify the user with a message: 
printf("enter -1 to stop entry\n"); 

//loop to scan user entries 
for(int i = 0; ; i++){ 
    scanf("%d", &b[i]); 

    if(i == max_entry - 1 && b[i] != -1){ 
     //increasing max entry 
     max_entry *= 2; 

     //reallocating to increase size of array 
     int *temp = NULL; 
     temp = realloc(b, max_entry * sizeof *b); 

     if(temp == NULL){ 
      //allocation failed, handle it 
     } 
     else{ 
      b = temp; 
     } 
    } 

    //break when user enters -1 
    if(b[i] == -1){ 
     break; 
    } 
} 
相關問題