[英]What to do with buffer in C
我正在嘗試使用一個返回char * buffer
的函數來捕獲來自標准輸入的隨機用戶輸入,並使用輸入返回char*
(即字符串),直到檢測到'\\n'
或'\\0'
作為輸入為止。
但是,函數user_input()
在第二次出現c = getchar();
崩潰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;
}
while ( c != '\n' || c !='\0' ) {
應該使用&&代替|| 否則循環永遠不會退出
while ( c != '\n' && c !='\0' ) {
盡管代碼中還有其他錯誤,例如“ buffer [num_read] ='\\ 0';”,但我還是構建了它並起作用了。 如果數組中確實有buffer_size項,最后可能會使緩沖區溢出。
這是我發現的問題:
stdin
上調用fflush()
。 它導致未定義的行為。 fflush()
僅用於輸出流。 c
的類型應為int
。 當沒有更多輸入時, getchar()
將返回EOF
,並且EOF
是不等於unsigned char
任何有效值的值。 這就是為什么getchar()
返回int
,因此您的接收getchar()
返回值的變量應該與該類型匹配。 while
檢查的感覺不正確。 僅當c
等於\\n
和\\0
時,您才退出循環,這是不可能的。 因此,循環將永遠不會退出。 如果實際上結束了提供給程序的輸入,則可能進入了無限循環,不斷分配直到系統內存耗盡。 因此,如果c
等於\\n
或\\0
則要退出循環。 c
為EOF
則應添加檢查以退出循環。 \\0
字符之前,應確保num_read
小於buffer_size
。 這可以通過將realloc()
代碼移動到while
循環的底部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;
}
我在下面修改了您的代碼。 嘗試按原樣運行它,首先使用'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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.