用户输入字符串到数组,导致缓冲区溢出

时间:2015-01-08 22:31:52

标签: c arrays user-input c-strings

我是C的新手,我正在研究一个程序,我要求用户以程序名的形式输入字符数组(字符串),将这些名称存储在一个数组中然后传递给这个数组到另一个功能。

现在,我尝试实现这一目标的最新方法是使用动态分配的数组,因为我不知道用户可能想要输入什么,这就是我如何做到的:

char *process;
process = (char *)malloc(sizeof(char) * (i+1));

然后我继续请求用户输入并使用printf确认输入:

printf("Enter process name: ");
scanf("%79s", &process); // take input, load into array
// fgets(process, sizeof(ARRAY_SIZE), stdin);
printf("You entered: %s\n", process[i]);

我已经尝试了scanf()fgets(),其中scanf()实际上有效,而fgets()会导致程序完全跳过我的printf语句并继续对此:

for(i = 0; i < ARRAY_SIZE; i++)
    printf("process = %s\n", process[i]);

程序以Segmentation Fault终止的位置。我理解这是由于用户输入超出了分配的缓冲区。

gdb打印进程的值时,它充满了垃圾(根据我的理解,C是在添加值之前C如何初始化数组)。在scanf("%79s", &process)之后,进程显示我在垃圾开头添加的输入而不是替换垃圾。我的问题是如何“清空”我的数组,以便我退出缓冲区?在这三天尝试了几种方法,我认为这与我错过了一些如何正确初始化我的数组的细节。我有#define ARRAY_SIZE 80这应该足以让这个功能发挥作用,但在以后的实现中可能还不够。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

变量process已经是指针,&process具有类型char**,并且是指向指针变量的指针,而不是指向已分配缓冲区的指针。

根据定义,

sizeof(char)始终等于1,因此在malloc()调用中不需要。如果您使用scanf(),则应该如此:

scanf( "%79s", process ) ;

但是因为字符串中的长度是硬编码的并且与iARRAY_SIZE无关,所以最好使用fgets(),但是使用长度参数{{1 }}与sizeof(ARRAY_LEN)相同;你的意思是sizeof(int)。在这种情况下,分配不一定是ARRAY_LEN,因为i + 1在给定的大小内插入了nul,因此:

fgets()

此外,几乎没有必要使用fgets( process, ARRAY_SIZE, stdin ) ; 作为固定长度的数组;您没有设置数组以适应输入,但限制输入以适合数组。既然如此,我建议:

malloc()

对于输入数据逐字符的输出,您需要char process[ARRAY_SIZE] ; printf( "Enter process name: " ) ; fgets( process, sizeof(process), stdin ) ; 格式说明符,而不是%c

%s

但是这将从数组中打印未使用的,单元化的字符,因此更有可能:

for( i = 0; i < ARRAY_SIZE; i++ )
    printf( "process = %c\n", process[i] ) ;

或者因为for( i = 0; process[i] != '\0'; i++ ) printf( "process = %c\n", process[i] ) ; 是一个以空字符结尾的字符串,只需:

process

所以你最需要的只是:

printf("process = %s\n", process ) ;

答案 1 :(得分:0)

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

int main() {
    char *process;
    int i = 0;//number of input character;
    size_t size;//Allocated size
    int ch;

    //process = (char *)malloc(sizeof(char) * (i+1));//+1 for '\0'
    size = 16;//Initial size
    process = malloc(size);//cast don't need in C

    printf("Enter process name: ");//fflush(stdout);
    while((ch = getchar())!=EOF && ch != '\n'){
        if(i == size -1){//-1 for NUL('\0')
            char *temp = realloc(process, size += 16);//expand size
            if(temp==NULL){
                fprintf(stderr, "failed to malloc\n");
                free(process);
                exit(EXIT_FAILURE);
            }
            process = temp;//successfully extended update
        }
        process[i++] = ch;
    }
    process[i] = 0;
    printf("process = %s\n", process);//type of process[i] is `char`
    free(process);
    return 0;
}