2016-03-14 68 views
0

所以我試圖編程一個功能,允許用戶輸入無限量的字符。例如:在C中獲取無限輸入?

char string[100] 

將輸入限制爲100個字符。

代碼中,我至今是:

#include<stdio.h> 

char* uinput(){ 
    char *string, *current; 
    int counter = 0; 
    string = (char *) malloc(10 * sizeof(char)); 
    do{ 
     realloc(string, counter * sizeof(char)); 
     current = string + counter; 
     *current = getchar(); 
     counter++; 
    }while(*current != '\n'); 
    return string; 
} 

int main(){ 
    char *s; 
    s = uinput(); 
    printf("\nYou entered: %s", *s); 
    return 0; 
} 

我是新來的指針,所以我不知道爲什麼,這並不工作(程序崩潰)。我試圖做的是不斷讀取一個字符,並繼續重新定位字符串指針,這樣字節數量不斷增加,直到用戶按下輸入('\ n')。

感謝 〜拉夫

+0

getline函數是一個簡單的答案。它最初是一個glibc擴展(即不是C標準庫),但它也應該在mingw下支持。如果您需要擔心跨平臺問題,那麼可以使用fgets和realloc來重新實現它。 –

+0

@rafaelThedoublemaster代碼有很多問題,我正在寫一個答案。 –

回答

1

該方法是理智的,但有一些小細節是錯誤的。如果您在啓用警告的情況下編譯,您會注意到您缺少<stdlib.h>;您也可以將的第一個字符改爲printf,而不是指向緩衝區的指針。

於是就有了明顯的錯誤,你的尺寸被重置爲0,而你casting the return value of malloc,使用char存儲的getchar()的結果,這也是錯誤的,因爲你無法對證EOF。您不保存realloc ed指針;而且你沒有正確地終止字符串。在較小的細節上,您需要將每個realloc中的緩衝區大小加倍,因爲realloc需要可能複製整條線,因此隨着線條長度的增長,它會變慢和變慢。

因此,我們得到:

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

char* uinput() { 
    char *string; 
    // number of characters in the buffer 
    size_t counter = 0; 

    // size of allocated buffer 
    size_t allocated = 16; 

    int c; 
    string = malloc(allocated); // sizeof(char) is 1 
    do { 
     c = getchar(); 
     if (c == EOF) { 
      break; 
     } 
     // if our buffer is too small, double the allocation 
     if (counter + 2 <= allocated) { 
      size_t new_size = allocated * 2; 
      char *new_buffer = realloc(string, new_size); 
      if (! new_buffer) { 
       // out of memory? try smaller increment 
       new_size = allocated + 16; 
       new_buffer = realloc(string, new_size); 
       if (! new_buffer) { 
        // really out of memory: free old block 
        free(string); 
        return NULL; 
       } 
      } 
      allocated = new_size; 
      string = new_buffer; 
     } 
     // store the character 
     string[counter++] = c; 
    } while (c != '\n'); 

    // terminate the buffer properly 
    string[counter] = 0; 
    return string; 
} 

int main() { 
    char *s = uinput(); 
    if (!s) { 
     // possibly out of memory in uinput 
     perror("Error reading input"); 
     exit(EXIT_FAILURE); 
    } 
    printf("\nYou entered: %s", s); 
    free(s); 
    return EXIT_SUCCESS; 
} 
+0

希望我沒有在我的UB中做太多UB。我想我必須提供一個PD getline實現:D –

+0

哇謝謝你的回答:D更多我需要了解的東西C. 順便說一句你能解釋EOF嗎?我第一次看到它 –

+0

文件結束。如果您在Linux中按下'ctrl-d',或在窗口上按下'ctrl-z';或者如果你想使用這種方法來處理文件(你可以使用'fgetc'而不是'getchar') –

2

好,我覺得這是allocing重新

realloc(string, counter * sizeof(char));

問題

你是什麼將是在第一次迭代字符串的大小?它將是0

現在您正在寫入一個指針,該指針的0字節已分配,因此分段錯誤。

將其更改爲while loop可以幫助解決該問題。您也可以更改計數器的初始值來修復它

+0

發生錯誤,發現錯誤。 –

+0

確實發現了:D我只是試圖將計數器更改爲1,但程序仍然崩潰(未響應) –

0

你可以嘗試像以下:

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

struct person{ 
    char *name; 
}pers; 

void addMem(void); 

int main(void){ 
    addMem(); 

    printf("\nYour name is:> %s\n",pers.name); 
    free(pers.name); 
    pers.name = NULL; 
    return 0; 
} 

void addMem(void){ 
    unsigned int length = 6; 
    size_t newLength = 0; 
    unsigned int newSize = 0; 
    unsigned int i =0; 
    char *name; 
    int c; 

    name = malloc(length); 
    if(name == NULL){ 
     exit(1); 
    } 
    newSize = length; 

    printf("Enter your name:> "); 

    while ((c = getchar()) != '\n' && c!=EOF){ 
     name[i++]=(char)c; 

     if(i == newSize){ 
      newSize = i+length; 
      name = realloc(name, newSize); 
     } 
    } 

    name[i] = '\0'; 

    newLength = strlen(name)+1; 
    pers.name = malloc(newLength); 

    memcpy(pers.name, name, newLength); 

    free(name); 
    name = NULL; 
} 
+0

千萬不要像這樣調用'realloc':'name = realloc(name,newSize)' - 它失敗了,那麼你有內存泄漏 - 使用一個臨時指針,直到你知道'realloc'是否成功。 –

0

另一種方法是使用fgets(),它得到一個字符串轉換成從輸入流的大小的緩衝區;如果它有完整的輸入,則字符串以\n結尾;如果它不,那麼它不會。因此,您可以循環調用fgets,直到最後有一個EOL字符,然後根據您的程序對輸入做什麼,您可以決定是保持重新分配還是一次處理輸入。