讀取不定長字符串輸入

  C語言一般使用scanf處理輸入,若是要讀取字符串,那麼就須要定義一個字符數組(char[])。但是,若是數組定義長度不足,就可能發生溢出。數組

  在C語言裏有個能夠用來讀取字符的函數(getchar),咱們能夠利用這個函數來實現不定長的字符串輸入。下面咱們就來說講如何作到這一點。函數

  首先,說一下原理:getchar每次只能讀取一個字符。所以,我經過循環使用getchar逐個讀取字符的方式,將全部輸入字符讀取。指針

  那麼,咱們要先解決一個問題:code

    何時結束循環再也不讀取呢?內存

  當咱們輸入字符串後,按下Enter鍵,那麼輸入的字符串就會被程序接收,寫入輸入緩衝區的除了剛纔輸入的字符串,還會有一個換行符\n,所以getchar當讀取到字符\n時,便可跳出循環,完成讀取。跳出循環後咱們還要在後面加上\0,這樣,它才能成爲一個真正的字符串。字符串

  第二問題:get

    存放在哪兒?class

  當咱們使用scanf讀取字符串時,咱們將字符串存放在字符數組(char[])裏面,那麼咱們使用循環讀取字符時,就須要有一個一樣連續的內存空間來存放讀取到的字符。並且,咱們由於不知道到底會讀取到多長的字符串,長度是不固定的,因此使用malloc來動態申請一個連續的內存空間。原理

  所以,咱們準備兩塊內存指針:內存泄漏

char* str;  
char* _str;

先給其中一個分配2個char的內存空間(一個用來存\0),同時用i來記錄輸入字符串的個數。

int i = 1;  
str = (char*)malloc(sizeof(char) * (i + 1));

而後,再用循環讀取字符,並把它存到申請的內存空間。

while('\n' != (str[i - 1] = getchar()))
{  
     i++;  
     ...  
}

  每次咱們讀取到一個字符時,就將i加一。因此循環體開始的時候是i++(剛讀完一個字符)。

  如今,重點來了,由於咱們要預先申請多一個長度的內存,而後才能繼續存放接下來要讀的字符。因此咱們須要把str釋放掉,而後從新申請空間,但是,直接釋放會把原來讀的字符都弄丟,因此就到_str出場了。

  咱們先給_str申請與str相同長的內存空間 。而後,把str的內容拷貝到_str裏。這時,就能夠把str釋放掉了。在給str從新申請內存空間成功後,把_str的內容拷貝回來,而後釋放掉_str就行了。

_str = (char*)malloc(strlen(str) + 1);  
str[i - 1] = '\0';
strcpy(_str, str);  
free(str);  
str = (char*)malloc(sizeof(char) * (i + 1));  
if(NULL == str)  
{  
     free(_str);  
     printf("No enough memory!");  
     return NULL;  
}  
strcpy(str, _str);  
free(_str);

  值得注意的是,在給str從新申請內存空間後,須要判斷一下str內存申請是否成功。若是失敗(NULL == str),咱們須要先將_str釋放掉(防止出現內存泄漏),再return NULL

  最後,咱們只要將\0加上,把str的內存地址返回,就大功告成了。

str[i - 1]='\0';  
return str;

附上完整代碼:

char* getstr()  
{  
        char* str;  
        char* _str;  
        int i = 1;  
        str = (char*)malloc(sizeof(char) * (i + 1));  
        while('\n' != (str[i - 1] = getchar()))  
        {  
                i ++;  
                _str = (char*)malloc(strlen(str) + 1); 
                str[i - 1] = '\0'; 
                strcpy(_str, str);  
                free(str);  
                str = (char*)malloc(sizeof(char) * (i + 1));  
                if(NULL == str)  
                {  
                        free(_str);  
                        printf("No enough memory!");  
                        return NULL;  
                }  
                strcpy(str, _str);  
                free(_str);  
        }  
        str[i - 1] = '\0';  
        return str;  
}
相關文章
相關標籤/搜索