读取不定长字符串输入

  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;  
}
相关文章
相关标签/搜索