问题:我需要能够识别连续出现两个空格的时间。
我已阅读以下问题:
how to read a string from a \n delimited file
我知道scanf问题:http://c-faq.com/stdio/scanfprobs.html
输入将采用以下格式:
1 5 3 2 4 6 2 1 9 0
两个空格表示需要处理下一组数据并与其自身进行比较。线的长度未知,每组中的数字或整数是未知的。两个空格是分隔下一个数据集的最多空格。
虽然我可以使用fgets和各种内置函数来解决这个问题,但我现在处理scanf问题可能会更容易。但是,如果不是这样,使用fgets,strtok和atoi将完成大部分工作,但我仍需要连续识别两个空格。
以下将采用整数,直到输入非整数。
while ( scanf ( "%d", &x ) == 1 )
我需要做的是读取空格,如果有两个连续的空格,我会让程序对下一组数据做一些不同的事情。
一旦我得到一个白色空间,我不知道该怎么说:
if ((input == "whitespace") && (previousInput == "whitespace")) ya da ya da else (input == "whitespace") ya da ya da else ya da ya da
感谢您的时间,感谢您的帮助。
获得的经验教训: 虽然下面由Jonathan Leffler发布了scanf的解决方案,但解决方案对于getc来说更简单一些(通过对内部scanf,正则表达式和char的更少了解)。回想起正则表达式的更好的知识,scanf和char会使问题变得更容易,当然知道哪些函数是可用的,哪一个是从一开始就使用的最好的函数。
答案 0 :(得分: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;
}
演示
编辑 Rahhhhhhhhh ......我将其上传为C ++。这是完全相同的事情,但现在C99 strict
(http://ideone.com/mGeVk)
答案 1 :(得分:1)
while ( scanf ( "%c", &x ) == 1 )
使用%c
可以读取空格字符,只能读取所有数据并存储在数组中。然后分配char* cptr
并将cptr
设置为数组的开头,然后分析数组,如果要读取十进制数,则可以在sscanf
上使用cptr
想要读取小数,但你必须在数组上有一个好位置的指针(数字你想读的数字)
if (((*(cptr + 1)) == ' ') && ((*cptr)== ' '))
ya da ya da
else ((*cptr)== ' '))
ya da ya da
sscanf(++cptr, "%d", &x);
else
ya da ya da
答案 2 :(得分: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()
。提醒我不要在你的大学上课。
答案 3 :(得分:0)
如果您真的需要scanf
类型功能,可以使用fgets
和sscanf
,并使用%n
说明符获取scanf,为您的程序提供偏移量每个空白跨越的开始和结束,同时完成其余的工作。
否则,抛弃整个scanf
家庭。在我看来,它很可能是标准库中最无用的部分。
答案 4 :(得分: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;
}