繁体   English   中英

C fgets语义错误

[英]C fgets semantic error

我是C语言世界中的新手,并且fgets()函数存在问题。 我用Google搜索了将近2个小时的错误,发现了不同的解决方案,但没有人能解决。

我的课程太大了,无法显示课程的每个部分,但让我向您展示有问题的部分:

//... kivansag is a struct(!)
if(check == 1){
        char name;
        printf("Please give me your nickname!\n");
        scanf("%s", &name);
        strcpy(kivansag.name,&name);

        char city;
        printf("Please give me your city!\n");
        scanf("%s", &city);
        strcpy(kivansag.city,&city);

        char *address = malloc(100);
        printf("Please give me your address!\n");           
        fgets(address,100,stdin);

        if((strlen(address)>0) && address[strlen(address)-1] == '\n'){
            address[strlen(address)-1] = '\0';
        }

        strcpy(kivansag.address,address);
        free(address);
}//...

问题是:每次我运行此代码时,正在运行的服务器在写出“给我您的地址”后都跳过fgets() ,并执行以下功能。

我可以得到任何建议吗?

更新:

现在我只有这个:

        printf("Please give me your address!\n");           
        fgets(kivansag.address,sizeof(kivansag.address),stdin);

        if((strlen(kivansag.address)>0) && kivansag.address[strlen(kivansag.address)-1] == '\n'){
            kivansag.address[strlen(kivansag.address)-1] = '\0';
        }

该结构看起来像这样:

struct Kivansag{
  //...
  char address[100];
};

是的,仍然跳过了我的部分...我也尝试使用fflush(stdin)来确保一切都清楚了,但没有用。

 scanf("%s", &name);      //you cant use %s to take input in a char variable
 ...
 scanf("%s", &city);

在这些namecity有两个char变量,而不是以null terminated字符串。 因此,使用此处-

strcpy(kivansag.name,&name);

导致UB

您可以将它们声明为数组-

char name[20];
char city[20];
fgets(name,20,stdin);    
...
fgets(city,20,stdin); 
strcpy(kivansag.name,name);      // note address of name is not required 
/* similarly for copying city */

因此,由于下一个fgets也不会被跳过。

然后照常做。

char只是一个字符,您不能使用它来读取scanf具有%s格式的字符串。 您需要提供一个字符数组。 无需扫描到一个变量然后复制到另一个变量,您可以直接扫描到结构成员。

scanf("%s", kivansag.name);

您也可以直接在变量中使用fgets()

fgets(kivansag.address, sizeof kivansag.address, stdin);
size_t len = strlen(kivansag.address);
if((len>0) && kivansag.address[len-1] == '\n'){
    kivansag.address[len-1] = '\0';
}

在scanf之后,请参阅fgets不起作用,以了解程序为何跳​​过fgets及其修复方法。

这两行总是会产生不确定的行为。

未定义的行为可能导致任何结果,包括段错误事件

    char name;
    ....
    scanf("%s", &name);

函数scanf()始终将NUL字节附加到输入的字符串中。

char name只定义了一个字节。

“%s”没有限制,因此用户可以/将始终超出该一个字节的缓冲区。

建议类似:

    char name[30];
    ....
    if( 1 != scanf("%29s", &name) { // handle error }

这行:

scanf("%s", &city);

在输入流中留下换行符。

以下对fgets()的调用将看到换行符,并立即返回,除了换行符和NUL字节外,什么都没有放入输入缓冲区

这行很乱:

if((strlen(address)>0) && address[strlen(address)-1] == '\n'){
        address[strlen(address)-1] = '\0';
    }

可能会或可能不会找到嵌入的换行符,并用NUL字节覆盖它:建议:

if( char* newline = strstr( address, "\n" ) )
    *newline = '\0';

甚至有“更巧妙”的方法来替换字符串中的换行符,但是这种方法很容易理解。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM