【问题标题】:fgets Introducing new line in user's input [duplicate]fgets在用户输入中引入新行[重复]
【发布时间】:2014-09-02 11:06:45
【问题描述】:

我正在提示用户输入文件名,但是一旦用户按下回车键,它也会将其带入文件名。所以这个文件永远找不到。

int main (){
char file[100];
FILE *fp;

printf("Please enter a valid filename:\n");
fgets(file,100,stdin);
fp=fopen(file, "r");

if(!fp){
printf("File not found.\n"); \\This will always happen because a new line is added to the user's input.
return 1;}

如果我使用

scanf("%s", file);

该问题没有发生,但我听说 scanf 不是一个好用的函数,并且会引入新问题。 fgets如何解决换行问题?

【问题讨论】:

标签: c string file fgets


【解决方案1】:

fgets(file,100,stdin); 之后,执行file[strlen(file)-1]='\0';,它将从代码中删除\n。要使用strlen() 函数,您需要在代码中包含string.h

试试这个修改后的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (){

    char file[100];
    FILE *fp;

    printf("Please enter a valid filename:\n");

    fgets(file,100,stdin);
    file[strlen(file)-1]='\0'; //Removing \n from input
    fp=fopen(file, "r");

    if(fp==NULL)
    {
        printf("File not found.\n");
        return 1;
    }
    else
    {
        printf("File found!\n");
        fclose(fp);
        return 0;
    }
}

【讨论】:

    【解决方案2】:

    fgets() 返回 \n 新行代码......这就是它的作用。你必须消灭那个角色。

    鉴于溢出或至少完全填充传入缓冲区是一种流行的攻击向量,我更喜欢防御这种攻击的代码。

    字符 *cp; 文件[(文件大小)-1)] = '\0'; /* 确保在缓冲区填充攻击中 \0 终止 */ cp = strchr( 文件, '\n' ); /* 找到预期的 \n,但允许没有 */ 如果 ( cp ) *cp = '\0'; /* 安全清除关闭\n */

    【讨论】:

    • 你的心在正确的地方,但\0检查并不能阻止读取未初始化的数据。相反,您可以检查fgets 的返回值。如果它返回NULL,则根本不要阅读file;否则可以保证缓冲区包含一个字符串。
    • 挑战:自从您发表评论以来已经有一段时间了,但您的话中没有任何内容涉及缓冲区完全满的情况,这是我所提防的。当然 fgets() 在 EOF/Error 上返回 NULL,但这是另一个错误。我要防止最后的 \n\0 未发布的过长名称,因为它们会超出缓冲区的末尾。没有好的 fputs() 应该允许这样做(但我倾向于有两个额外的保护字节,因为担心 fgets() 有问题)。 fgets() 返回值中没有任何内容可以提示您缓冲区已满。称我为偏执狂,但我担心缓冲区溢出是意外或设计造成的。
    猜你喜欢
    • 2014-12-06
    • 2021-08-06
    • 2016-05-06
    • 1970-01-01
    • 2017-07-07
    • 2017-10-16
    • 2015-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多