【问题标题】:gets_s() is getting skippedgets_s() 被跳过
【发布时间】:2017-02-20 19:52:25
【问题描述】:

我有这段代码应该要求用户输入一些信息:

char * nome = malloc(256);
char * cc = malloc(256);
char * morada = malloc(256);
char * tlf = malloc(20);
printf("Novo nome:");
gets_s(nome, sizeof(nome));
printf("Nova Morada:");
fflush(stdin);
gets_s(morada, sizeof(morada));
printf("Cartao de cidadao:");
fflush(stdin);
gets_s(cc, sizeof(cc));
printf("Novo Contacto:");
fflush(stdin);
gets_s(tlf, sizeof(tlf));

第一个gets_s() 被跳过,我不明白为什么,我也尝试使用scanf("%s",nome) 并尝试使用我通过堆栈溢出找到的一些解决方案,因为据我所知scanf() 发生的情况是最后一个字符实际上是“自动”读取的,因为它没有在之前的 scanf() 上使用,但我认为情况并非如此,因为我已经尝试了我能找到的每一个建议。 谁能解释一下为什么会这样?

编辑:

char nome[256];
char cc[256];
char morada[256];
char tlf[20];

printf("Novo nome:");
fflush(stdin);
scanf("%s", nome);

printf("Nova Morada:");
fflush(stdin);
scanf("%s", morada);

printf("Cartao de cidadao:");
fflush(stdin);
scanf("%s", cc);

printf("Novo Contacto:");
fflush(stdin);
scanf("%s", tlf);

【问题讨论】:

  • 1) fflush(stdin); 调用未定义的行为 2) 您没有检查 mallocgets_s 的任何结果。 3) 边界检查接口是可选的。为什么不使用fgets? 4) 指针不是数组。 5) 拿起你的 C 书,看看 sizeof 做了什么。
  • 感谢您的评论。首先,“调用未定义的行为”是什么意思?我已经按照你的建议使用了 fgets() 但结果是一样的,我已经放弃了 fflush() 因为我从你的评论中了解到它的行为没有定义,因此不确定它是否会清理缓冲区。仍然得到相同的结果
  • 您最大的问题是不恰当地使用sizeof
  • 在此之前有没有读取输入的代码?如果您将gets_s()scanf() 混合使用,则必须小心。
  • sizeof(nome) 可能只是4,因为它是指针的大小,而不是它指向的缓冲区的大小。

标签: c string format scanf


【解决方案1】:

当您要读取包含空格的字符串时,使用fgets() 比使用scanf() 更容易。另请注意,根据标准,fflush(stdin) 会导致未定义的行为,尽管 Microsoft 支持此用法的已定义行为。不过,它不是可移植的,可能永远不应该使用。

当您使用fgets() 读取一行输入时,尾随换行符存储在输入缓冲区中,因此您可能需要将其删除。有很多方法可以做到这一点,但这里我使用string.h 中的strchr() 函数编写了一个小函数eat_newline(),它可以找到换行符并将其替换为空字符。

虽然这里没有使用fgets(),但它的一个优点是您可以读取一行输入,然后使用sscanf() 解析它,就像使用@一样987654330@,但具有更多控制权,并且能够重新扫描同一行输入。

#include <stdio.h>
#include <string.h>

void eat_newline(char *str)
{
    char *find;    
    if ((find = strchr(str, '\n')) != NULL) {
        *find = '\0';
    }    
}

int main(void)
{
    char nome[256];
    char cc[256];
    char morada[256];
    char tlf[20];

    printf("Novo nome:");
    fgets(nome, sizeof nome, stdin);
    eat_newline(nome);

    printf("Nova Morada:");
    fgets(morada, sizeof morada, stdin);
    eat_newline(morada);

    printf("Cartao de cidadao:");
    fgets(cc, sizeof cc, stdin);
    eat_newline(cc);

    printf("Novo Contacto:");
    fgets(tlf, sizeof tlf, stdin);
    eat_newline(tlf);

    printf("nome: %s\n", nome);
    printf("morada: %s\n", morada);
    printf("cc: %s\n", cc);
    printf("tlf: %s\n", tlf);

    return 0;
}

【讨论】:

  • 这是迄今为止最好的答案,也是真正解决了我的问题的答案。感谢您的详细回答和示例,先生
猜你喜欢
  • 2013-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-04
  • 2015-08-23
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
相关资源
最近更新 更多