C - Ignore spaces in scanf()
我正在尝试进行简单的字符串获取。 我需要从输入(stdin)编写一个字符串,该字符串可以包含空格,并保存单词之间没有任何空格。
到目前为止,我已经编写了可以保存所有内容(还包括空格)的简单代码,但是我不知道如何使
1 2 3 4 5 6 |
例如:
如果我的输入是:
我尝试使用
我也知道我可以在保存字符串后"重新扫描"字符串并删除所有空格,但是我需要尽可能高效地进行此采集,并且重新扫描每个字符串以删除空格会大大增加计算时间(而不是 只是扫描和忽略,其复杂度为O(n))
您使用的工具错误。您需要使用getc
并执行以下操作
1 2 3 4 5 6 7 8 9 10 11 12 13 |
无需重新扫描
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
另请注意,您的代码有问题:
-
scanf() 格式字符串未终止 -
尾随的
s 不正确,格式仅为%[^\
] -
在空终止符之前指定要存储到数组中的最大字节数比较安全:
scanf("%9[^\
]", str); -
您应该测试
scanf() 的返回值,以避免转换失败(例如在空行或空文件上)时将未初始化的数组传递给printf 。
您可能会使用
如果有兴趣从输入中除去其他空格(除了"
' ' (0x20) space (SPC)
'\\t' (0x09) horizontal tab (TAB)
'\
' (0x0a) newline (LF)
'\\v' (0x0b) vertical tab (VT)
'\\f' (0x0c) feed (FF)
'\
' (0x0d) carriage return (CR)
本示例使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | int main(void) { char string[] = {"this contain's \ whitespace\\t"}; int len = strlen(string); char out[len+1];// +1 for null terminator //(accommodates when input contains no whitespace) int count = clean_whitespace(string, out); return 0; } int clean_whitespace(const char *in, char *out) { int len, count=0, i; if((in) && (out)) { len = strlen(in); for(i=0;i<len;i++) { if(!isspace(in[i])) { out[count++] = in[i]; } } out[count]=0;//add null terminator. } return count; } |
So far i've written this simple code which saves everything (also
spaces), but i don't know how to make thescanf() ignore the spaces.
您是从与大多数新C程序员相反的方向来解决这个问题的。问题通常不是使
但是你不能吃蛋糕也不能吃。字段指令
]
如果要继续使用
- 读取数据后删除空格,或者
- 读取并传输以空格分隔的片段作为单独的字段。
另一个答案已经描述了如何做前者。您可以按照以下步骤进行操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | int main(void) { int field_count; do { char str[80]; char tail; field_count = scanf("%79[^ \ ]%c", str, &tail)); if (field_count == 0) { // No string was scanned this iteration: the first available char // was a space or newline. Consume it, then proceed appropriately. field_count = scanf("%c", &tail); if (field_count != 1 || tail == '\ ') { // newline, end-of-file, or error: break out of the loop break; } // else it's a space -- ignore it } else if (field_count > 0) { // A string was scanned; print it: printf("%s", str); if (field_count == 2) { // A trailing character was scanned, too; take appropriate action: if (tail == '\ ') { break; } else if (tail != ' ') { putchar(tail); } // else it is a space; ignore it } } // else field_count == EOF } while (field_count != EOF); } |
注意事项:
-
scanf %79[^ \ 指令中的79个字符(最大)字段宽度。如果没有字段宽度,则存在严重的错误,可能会超出数组边界(必须至少比字段长一个字符才能使用字符串终止符)。
] -
[ 是字段类型,而不是限定符。s 是一个单独的字段类型,它也处理字符串,但是具有不同的行为;此处不使用s 字段。 -
scanf 的返回值告诉您成功扫描了多少个字段,如果输入和格式之间不匹配,或者到达输入的末尾,或者发生I / O错误。需要考虑这些可能性。 -
如果实际上扫描了第二个字段
%c ,它使您可以确定前面的字符串字段是否由于字段宽度已用尽而没有到达空格或换行符,是否观察到空格或是否因为观察到换行符。这些情况中的每一个都需要不同的处理。 -
尽管
scanf 跳过大多数字段类型的前导空白,但%[ 和%c 字段是三个例外中的两个。 -
这种方法专门跳过空格字符(
' ' );它不会跳过其他空白字符,例如水平和垂直制表符,回车,换页等。这种方法也可以适用于处理这些空白,但是所提供的内容足以证明这一点。
我发布此消息是为了证明使用scanf也可以解决此问题。
1 2 3 4 5 6 7 8 | int main() { char a[10]; for(int i = 0; i < 10 ; i++){ scanf("%c", &a[i]); if( a[i] == ' ') i--; } } |
上面的代码只扫描了10个字符,中间没有空格。
这是您要用其他内容替换空格的方法,例如:','
如果您希望输入包含更多字符,只需定义一个新变量x并将10更改为x,将9更改为x-1