9

问题:我需要能够识别两个空格何时连续出现。

我已阅读以下问题:

如何从 \n 分隔文件中读取字符串

如何读取带有空格的scanf

我知道scanf问题:http ://c-faq.com/stdio/scanfprobs.html

输入将采用以下格式:

1 5 3 2  4 6 2  1 9  0

两个空格表示需要处理下一组数据并与自身进行比较。线的长度是未知的,每组中的数字或整数是未知的。两个空格最多可以分隔下一个数据集。

虽然我可以使用 fgets 和各种内置函数来解决这个问题,但我现在使用 scanf 解决问题可能会更容易。但是,如果不是这样,使用 fgets、strtok 和 atoi 将完成大部分工作,但我仍然需要连续识别两个空格。

以下将采用整数,直到输入非整数。

而 ( scanf ( "%d", &x ) == 1 )

我需要它做的是读取空格,如果有两个连续的空格,我将程序对下一组数据做一些不同的事情。

一旦我得到一个空白,我不知道该怎么说:

if ((input == "whitespace") && (previousInput == "whitespace"))
  呀呀呀呀
否则(输入==“空白”)
  呀呀呀呀
别的
  呀呀呀呀

感谢您的宝贵时间,并感谢您的帮助。

经验教训: 虽然 Jonathan Leffler 在下面发布了 scanf 的解决方案,但使用 getc 解决方案更简单一些(通过对内部 scanf、正则表达式和 char 的了解较少)。回想一下对正则表达式的更好了解,scanf 和 char 会使问题变得更容易,并且当然知道哪些函数可用,以及从一开始就最好使用哪个函数。

4

5 回答 5

5

getc并且ungetc是你的朋友

#include <stdio.h>

int main(void) {
  int ch, spaces, x;
  while (1) {
    spaces = 0;
    while (((ch = getc(stdin)) != EOF) && (ch == ' ')) spaces++;
    if (ch == EOF) break;
    ungetc(ch, stdin);
    if (scanf("%d", &x) != 1) break;
    printf("%d was preceded by %d spaces\n", x, spaces);
  }
  return 0;
}

演示在http://ideone.com/xipm1

编辑Rahhhhhhhhh ...我将其上传为 C++。这是完全相同的事情,但现在C99 stricthttp://ideone.com/mGeVk

于 2010-09-21T22:51:45.443 回答
1
while ( scanf ( "%c", &x ) == 1 )

使用%c您可以读取空白字符,您必须只读取所有数据并存储在数组中。然后分配char* cptr并设置cptr为数组的开头,然后分析你的数组,如果你想读取十进制数,你可以在你想读取十进制数时简单地使用sscanfcptr但你必须在数组上的正确位置有指针(在你想要的数字上读)

if (((*(cptr + 1)) == ' ') && ((*cptr)== ' '))
  ya da ya da
else ((*cptr)== ' '))
  ya da ya da
  sscanf(++cptr, "%d", &x);
else 
  ya da ya da
于 2010-09-21T22:42:23.033 回答
0

你对“空白”的定义是什么?

坦率地说,我不认为我想尝试使用scanf()来识别双空格。几乎所有其他方法都会容易得多。

但是,如果您坚持做不那么明智的做法,那么您可能希望使用从以下派生的代码:

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

int main(void)
{
    int d;
    char sp[3] = "";
    int n;

    while ((n = scanf("%d%2[ \t]", &d, sp)) > 0)
    {
        printf("n = %d; d = %d; sp = <<%s>>", n, d, sp);
        if (n == 2 && strlen(sp) == 2)
            printf(" end of group");
        putchar('\n');
    }
    return 0;
}

方括号括起一个字符类和前面的 2,它坚持最多 2 个来自该类的字符。您可能不得不担心它会读取换行符并尝试获取更多数据以满足字符类 - 这可以通过从字符类中删除换行符来解决。但这取决于您对空白的定义,以及组是否自动以换行符结束。sp[0] = '\0';在循环结束时重置不会有什么坏处。

也许,您最好反转字段,以检测数字前的两个空格。但这在普通情况下会失败,所以你会回到一个简单的"%d"格式来读取数字(如果失败,你知道你既没有空格也没有数字 - 错误)。请注意,%d咀嚼前导空白(由标准定义) - 所有这些。

我越看这个,我就越不喜欢 ' scanf()only. 请提醒我不要在你们大学上课。

于 2010-09-21T22:53:25.170 回答
0

如果您真的想要scanf类型功能,您可以使用fgetsand sscanf,并使用说明%n符来获取 scanf 为您的程序提供每个空白跨度的开头和结尾的偏移量,同时它会完成其余工作。

否则,抛弃scanf全家。在我看来,它很可能是标准库中最没用的部分。

于 2010-09-21T23:04:19.093 回答
0

这是一个仅使用 scanf() 函数的解决方案。我在这个示例中使用了 sscanf() 来实现大致相同的功能。

#include <stdio.h>


int p_1_cnt = 0, p_2_cnt = 0;

void process_1(int x)
{
    p_1_cnt++;
}


void process_2(int x)
{
    p_2_cnt++;
}


char * input_line = "1 5 3 2  4 6 2  1 9  0";

int main(void)
{
    char * ip = input_line;

    int x = 0, ws_0 = 0, ws_1 = 0, preceding_spaces = 1, fields = -2;

    while (sscanf (ip, "%d%n %n", &x, &ws_0, &ws_1) > 0)
    {
        ip += ws_0;

        if ((preceding_spaces) == 1)
            process_1(x);
        else
            process_2(x);

        preceding_spaces = ws_1 - ws_0;
    }

    printf("\np_1_cnt = %d, p_2_cnt = %d", p_1_cnt, p_2_cnt);
    _fgetchar();

    return 0;
}
于 2015-02-03T17:44:59.797 回答