【问题标题】:Scanf function stops after newline and reads just a small part of input ( should ignore newline and tabs )Scanf 函数在换行符后停止并仅读取一小部分输入(应忽略换行符和制表符)
【发布时间】:2019-07-24 09:29:21
【问题描述】:

整个问题的简短版本:

我想加载这个输入

4
     CAAC

      28    EAAEB5
  F489AD95

但我能从中得到的只有:

4                                                                                                                                                                                           

我正在尝试从该输入中生成这些参数:4CAAC28EAAEB5F489AD95

--------------- 用我的代码详细解释 ---------------

我是 C 语言的新手,我正在尝试输入,作为字符串并在之后使用它......我在处理 "Whitespaces" 时遇到问题,例如 [ "\n" ,@987654331 @ 和 " " ] 这是我给编译器的输入:

4
     CAAC

      28    EAAEB5
  F489AD95

有一堆空格,制表符等。我想做的事情是阅读它并替换 \n 和 \t (在下面的 clode 中我试图忽略它,因为在 scanf() 找到 \ n 它会跳过其余部分。

这是我目前尝试的代码之一:

#include <stdio.h>

int main()
{
    int number;
    char chr[200];

    // %d -> I know that there should be number at the beginning, so until character / space appears, I want to read the number.
    // scanf("%d", &number);

    // ignores \n and \t and then puts it in chr
    scanf(" %[^\t\n]s", &chr);

    // last should be \n so this is just acheck if there is ( its gonna be in if later )
    scanf("%c");

    printf("\n %s", chr);
    printf("\n Heythere");

    return 0;
}

这是我得到的输出:

4                                                                                                                                                                                           
 Heythere 

我一直在考虑把它放在一个循环中,但问题是,最后一个字符是“\n”,它可以在给定的字符串中出现多次。

我目前正在尝试为 scanf() 找到读取这些行并忽略新行的最佳选项

/////////

换句话说:

我正在尝试从该输入中生成这些参数:4CAAC28EAAEB5F489AD95

知道如何修复它,以便能够完全缓冲它吗? (也是对我有帮助的最佳答案,它将用一个“”(空格)替换那些“\n”和“\t”(空格)提前谢谢您的回答(如果它真的很简单,也很抱歉并回答百万次......我被困在这里一周)

【问题讨论】:

  • scanf(" %[^\t\n]s", &amp;chr); 是类型错误。此外,格式字符串中的 s 永远不会匹配。这也是等待发生的缓冲区溢出。 scanf("%c"); 具有未定义的行为(%c 缺少参数)。
  • 好的,所以在我修复 scanf("%c"); ,我应该如何修复 scanf(" %[^\t\n]s", &chr); ?
  • 我不知道,我得看看scanf 手册,我讨厌scanf,所以我通常不会打扰。
  • 这是X-Y problem吗?您是否真的在尝试读取 4CAAC28EAAEB5F489AD95 五个数据项而不使用任何分隔空格?
  • 我将编辑我的问题,使其更具可读性和易于理解

标签: c string char int scanf


【解决方案1】:

您有多种选择:

  • 在 IS 中使用官方讨论帖
  • 在他们的时间询问任何顾问
  • 或者,如果你不能来,再问他们一次
  • 给任何一位顾问写一封电子邮件

My feelings about this post

【讨论】:

  • 呵呵,我看到了ai没有其他选择,我已经打算在论坛上写了:)
  • 哦,我已经解决了这个问题,只使用小数和十六进制,我虽然它是一个新主题的答案
【解决方案2】:

从表面上看,你只需要一个循环来读取五个字符串:

char data[5][100];
int i;

for (i = 0; i < 5; i++)
{
    if (scanf("%99s", data[i]) != 1)
    {
        fprintf(stderr, "Unexpected input failure (i = %d)\n", i);
        exit(EXIT_FAILURE);
    }
}

现在数组的元素将包含您提供的 5 个字符串(“单词”)。

根据设计,scanf() 函数在很大程度上忽略空格,除非它分隔字符串或数字。除了三个转换说明符之外,所有转换说明符都跳过前导空格 - 例外是 %c%[…](扫描集)和 %n

%99s 转换规范会跳过前导空格(空格、制表符、换行符),最多消耗 99 个非空格字符,并在第一个空格处停止(或字符串已满时),留下如果字符串未满,输入流中的空白将由下一个输入处理。

显然,如果您不知道要读取五个字符串,则必须更加努力——但基本思想是相同的。

如果您想保留或更改换行符、制表符、空格,那么scanf() 不是该工作的正确工具。它不关心空白,而你关心——这不会带来幸福。然后您使用fgets() 或POSIX getline() 读取输入的行,您可以根据需要处理空格、制表符和换行符。

【讨论】:

  • 问题是它可以改变,它取决于输入,输入的数量也写为它的第一部分,问题是,如果字符串(这是一个例子:7BB CAB BB AA 2B 5B 7C
  • 这个问题应该更清楚。您读取数字(if (scanf("%d", &amp;num_strings) != 1) { fprintf(stderr, "Expected number but didn't get one\n"); exit(EXIT_FAILURE); },然后安排适当的内存分配。如果您只需要依次处理每个单词并且不需要将它们全部存储在数组中,那么您可以使用简单的char data[100]; 变量读取每个字符串,然后在循环中处理它。如果您需要同时将它们全部放在内存中,则需要分配内存。可能是char data[num_strings][100]; 或者可能使用malloc()
  • 但是到目前为止感谢您的回答:) 现在我认为我需要做的就是以某种方式将数字与字符分开,然后定义第一个数组值;)
  • 谢谢 :) 试试看它是否有效,如果它解决了问题会告诉你
  • 在我的代码中选择 100 是任意的——它足够大,可以读取大多数单词,但又小到不会成为大问题。请注意,如果num_strings 足够大,VLA(可变长度数组)分配 (char data[num_strings][100];) 可能会导致堆栈溢出。如果这个数字是(比如说)10,000 或更多——使用 1 MB 左右的内存——那么你可能应该使用动态内存分配。如果它不太可能那么大,那么 VLA 可能还可以。请注意,VLA 支持在 C99 中是强制性的,在 C11 中是可选的,但在 C90 中正式不存在。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多