【问题标题】:C , fgets() scans extra char while trying to scan a stringC , fgets() 在尝试扫描字符串时扫描额外的字符
【发布时间】:2017-01-08 17:42:28
【问题描述】:

问题是当你输入一个名字比如elvis(它有5个字母)时,它会打印这个:

Please enter your name.
elvis
Your name is elvis
 and it is 6 letters long.
Press any key to continue . . .

问题在于,它产生了另一条不必要的线,那是因为在 elvis 之后我按下了 enter。

对不起,我是新用户,我对这些规则很陌生,请纠正我并教育我,谢谢你的时间。

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

#define STR_LEN 7

int main(void)
{
    char name[10] = {0};
    printf("Please enter your name.\n");
    fgets(name ,10, stdin);
    printf("Your name is %s and it is %d letters long.\n" , name , strlen(name));
    system("PAUSE");
    return 0;
}

【问题讨论】:

  • I need a function that will solve this.,是的,对,但是对于那个说法,这是错误的地方,
  • 问题格式足够好;我已经提供了答案。

标签: c


【解决方案1】:

fgets 总是在末尾写上 '\n' 字符,如果它合适的话(当然,看到它)。所以你需要手动删除它。

(我知道,因为我在大学里对我的队友说过 20 次:/)

您需要检查最后一个字符是否为 '\n',如果是,请将其删除(用 0=='\0' 覆盖)。一些示例代码:

char str[256];
fgets(str, 256, stdin);
if (*str && str[strlen(str)-1] == '\n')
    str[strlen(str)-1] = 0;

(请注意,上面的代码假设 GCC 优化了纯函数调用。如果不是,则应将长度保存在单独的变量中以优化程序)

【讨论】:

  • ...这可以通过name[strcspn(name, "\n")] = '\0';完成
  • fgets 并不总是在末尾写一个 '\n'。 fgets 将在获得 '\n' 时停止读取,但也可能由于其他原因而停止。例如这里如果我们输入的长度超过 10 个字符,fgets 将停止并且我们不会有这个 '\n'。
  • @PaulStelian 我刚刚看到你在哪里写了 always rights [...] ,如果合适的话。一切都好。
  • @PaulStelian 什么“额外功能”?
  • @PaulStelian Er。这些功能已记录在案。您可以在手册中查找它(例如 unix 手册页)。
【解决方案2】:

正如其他伙伴已经告诉您的那样,fgets 从文件指针(在您的情况下为标准输入)获取字符,并在 name 中添加一个额外的 '\n'。 您可以轻松摆脱它,编写类似

的内容
name[strlen(name)-1] = '\0';

始终将您的 printf 格式化为 %lu 而不是 strlen(name) 上的 %d。

还有一个很好的提示,请始终检查函数返回时是否有错误。 请在此处发布后,始终咨询 linux man(fgets stdlib func),尝试一些示例,调试它们,即使在堆栈溢出时也可以在 Google 上搜索和阅读不错的搜索选项。(这不是讨厌,只是一个友好的一般建议)。

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

#define STR_LEN 7

int main(void)
{
    char name[10] = {0};
    printf("Please enter your name.\n");
    if (!fgets(name ,10, stdin)) {
        printf("Error reading from stdin");
        return 1;
    }

    size_t len = strlen(name);
    if (len > 0 && name[len-1] == '\n') {
        name[len-1] = '\0';
    }
    printf("Your name is %s and it is %lu letters long.\n" , name , strlen(name));
    system("PAUSE");
    return 0;
}

已编辑:(melpomene 建议)。

【讨论】:

  • name[strlen(name)-1] 是个坏主意。如果strlen(name) 恰好为 0,有趣的事情就会发生(好吧,在这种特殊情况下不会发生,但仍然如此)。此外,如果用户键入 9 个或更多字符,此代码会丢弃其中一个(name 的最后一个字符不能保证是 '\n')。
  • %lustrlen() 的错误格式,它返回 size_t,而不是 unsigned long
  • 是的,在 TIGCC 上:“TIGCC 是用于 TI-89、TI-92 Plus 和 V200 的 C/ASM 交叉编译器。”我怀疑这就是你的意思重新使用。
  • 是的,size_t 是一些未指定的无符号整数类型。我不明白你的意思。
  • 我猜想与size_t 的交易是MS 运行时库——它的某些(全部?)版本不支持printfz 格式修饰符,所以你必须假装size_tunsigned long 或进行显式转换。因为system("PAUSE"),我在这里猜到了 MS——这段代码是在 MS Visual Studio 中编程的症状。
猜你喜欢
  • 2012-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-20
  • 1970-01-01
  • 2017-10-12
  • 2023-03-24
相关资源
最近更新 更多