fgets()包括最后的换行符

Man*_*son 9 c string fgets

fgets(input,sizeof(input),stdin);
if (strcmp(input, "quit") == 0){
  exit(-1);
}
Run Code Online (Sandbox Code Playgroud)

如果我输入quit,它不会退出程序; 我想知道为什么会这样.

顺便input声明为char *input;.

cod*_*ict 13

该函数fgets可能会在字符串读取的末尾添加换行符.你必须检查:

size_t ln = strlen(input) - 1;
if (input[ln] == '\n')
    input[ln] = '\0';
Run Code Online (Sandbox Code Playgroud)

甚至

strtok(input, "\n");
Run Code Online (Sandbox Code Playgroud)

  • 如果第一个`char`读取是空字符,则`ln`取值为"SIZE_MAX",肯定会导致使用`input [ln]` - > UB读取越界.为了避免这种攻击,测试`ln`或者使用`ln [strcspn(ln,"\n")] = 0;`.`strtok(input,"\n");如果第一个`char`是''\n',``就不能删掉`'\n'. (2认同)

Ola*_*che 8

在您的输入中追踪换行符.见男人fgets.测试"退出"+换行,例如:

fgets(input,sizeof(input),stdin);
if(strcmp(input, "quit\n") == 0){
    exit(-1);
}
Run Code Online (Sandbox Code Playgroud)

我完全错过了最后一句话char *input.根据架构,input将长4或8个字节.所以代码是有效的

fgets(input, 8, stdin);
Run Code Online (Sandbox Code Playgroud)

这并不反映记忆的真实大小input.只要输入短于8个字节,这可能"有效",但如果输入较大,则会截断输入.此外,您下次打电话时将获得剩余的输入fgets.

您应该给出实际大小或者采用@ JonathanLeffler的建议并声明一个char数组,例如

char input[64];
fgets(input, sizeof(input), stdin);
Run Code Online (Sandbox Code Playgroud)

要么

char *input = malloc(N);
fgets(input, N, stdin);
Run Code Online (Sandbox Code Playgroud)

  • 可悲的是,这并不是一直有效.假设您已将输入声明为char输入[5]并输入quit.那时fgets不会在最后添加换行符.因此,请始终检查是否添加了换行符. (4认同)