我正在尝试使用一个返回char * buffer
的函数来捕获标准输入的随机用户输入,并返回一个char*
(即一个字符串),其输入为'\n'
或'\0'
被检测为输入。
然而,函数user_input()
在函数结尾附近c = getchar();
的第二次出现时崩溃了(在 //Error Here
评论处)。
我做错了什么?
char* user_input(){
char *buffer=NULL;
size_t num_read = 0;
size_t buffer_size = 100;
char c = '\0';
char *new_buffer=NULL;
buffer = malloc(buffer_size);
fflush(stdin);
c = getchar();
while ( c != '\n' || c !='\0' ) {
if (num_read >= buffer_size) {
new_buffer=NULL;
buffer_size *= 2; // try a buffer that's twice as big as before
new_buffer = realloc(buffer, buffer_size);
if (new_buffer == NULL) {
free(buffer);
return NULL;
/* Abort - out of memory */
}
buffer = new_buffer;
}
buffer[num_read] = c;
num_read++;
c = getchar(); //Error Here
}//while
buffer[num_read] = '\0';
return buffer;
}
答案 0 :(得分:2)
while ( c != '\n' || c !='\0' ) {
应该使用&&而不是||或者循环永远不会退出
while ( c != '\n' && c !='\0' ) {
我构建它并且它工作但是代码中还有其他错误,例如“buffer [num_read] ='\ 0';”如果数组中有确切的buffer_size项,那么最后可能会溢出缓冲区。
答案 1 :(得分:1)
以下是我发现的问题:
fflush()
上致电stdin
。它导致未定义的行为。 fflush()
仅适用于输出流。c
的类型应为int
。当没有更多输入时,getchar()
将返回EOF
,而EOF
的值不等于unsigned char
的任何有效值。这就是getchar()
返回int
的原因,因此接收getchar()
返回值的变量应与该类型匹配。while
检查的意义不正确。如果c
同时等于\n
和\0
,则只会离开循环,这是不可能的。因此循环永远不会退出。如果你实际上结束了给你的程序的输入,你可能进入了一个无限循环,不断分配,直到你的系统内存不足。因此,如果c
等于\n
或\0
,您希望离开循环。c
为EOF
,则应添加一项检查以离开循环。num_read
字符之前,您应确保buffer_size
小于\0
。这可以通过将realloc()
代码移到while
循环底部而不是顶部来完成。通过这些更改,代码如下所示:
char *user_input() {
char *buffer = NULL;
size_t num_read = 0;
size_t buffer_size = 100;
int c = '\0';
char *new_buffer = NULL;
buffer = malloc(buffer_size);
c = getchar();
while (!(c == EOF || c == '\n' || c == '\0')) {
assert(num_read < buffer_size);
buffer[num_read++] = c;
if (num_read >= buffer_size) {
buffer_size *= 2; // try a buffer that's twice as big as before
new_buffer = realloc(buffer, buffer_size);
if (new_buffer == NULL) {
free(buffer);
return NULL;
}
buffer = new_buffer;
}
c = getchar();
} //while
assert(num_read < buffer_size);
buffer[num_read] = '\0';
return buffer;
}
答案 2 :(得分:0)
我在下面修改了你的代码。尝试按原样运行它,首先使用'q'字符,然后您可以稍后尝试其他退出条件。顺便说一句,你的代码没有修改就行了,并没有为我崩溃(除非发生缓冲区溢出,但它永远不会离开while循环(正如Brian Walker指出的那样)。无论如何,在任何ANSI C编译器中尝试这个: (只是不要输入超过1000个条目:)。
#include <ansi_c.h>
char* user_input(void);
int main(void)
{
char *buf;
buf = malloc(1000);
//SearchDirectory("C:\\dev");
sprintf(buf, "%s", user_input());
printf("%s", buf);
free(buf);
return 0;
}
char* user_input(void){
char *buffer=NULL;
size_t num_read = 0;
size_t buffer_size = 100;
char c = '\0';
char *new_buffer=NULL;
buffer = malloc(buffer_size);
fflush(stdin);
c = getchar();
while ( c != 'q' ) {
if (num_read >= buffer_size) {
new_buffer=NULL;
buffer_size *= 2; // try a buffer that's twice as big as before
new_buffer = realloc(buffer, buffer_size);
if (new_buffer == NULL) {
free(buffer);
return NULL;
/* Abort - out of memory */
}
buffer = new_buffer;
}
buffer[num_read] = c;
num_read++;
c = getchar();
}//while
buffer[num_read] = '\0';
return buffer;
}