C语言 使用 scanf 忽略分隔字符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17214026/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ignoring separating character using scanf
提问by Thongurf
The problem: I am attempting to use scanf to read a sentence with fields seperate by | ,so naturally i use the scanf's natural features to ignore this symbol but it then also ignores everything that has a | in it.
问题:我试图使用 scanf 来阅读一个由 | 分隔的字段的句子。,所以我很自然地使用 scanf 的自然特征来忽略这个符号,但它也忽略了所有带有 | 的东西。在里面。
The code, simplified:
代码,简化:
int main(){
char* a=malloc(8);
char* b=malloc(8);
scanf("%s | %s",a,b);
printf("%s %s",a,b);
}
when i attempt the input:
当我尝试输入时:
TEST | ME
测试 | 我
it works as intended, but when i have the following case:
它按预期工作,但是当我遇到以下情况时:
TEST ME|
测试我|
it naturally reads the test, but ignores the ME|, is there any way around this?
它自然会读取测试,但忽略了 ME|,有什么办法可以解决这个问题吗?
回答by BLUEPIXY
scanf("%[^ \t|]%*[ \t|]%[^ \t\n|]", a,b);
printf("%s %s",a,b);
Annotation:
注解:
%*: ignore this element.
%*: 忽略这个元素。
E.g. %*s//skip the reading of the text of this one
eg %*s//跳过阅读这一段的文字
%[character set(allow)]: Read only character set that you specify.
%[character set(allow)]: 只读您指定的字符集。
E.g. %[0123456789]or %[0-9]//Read as a string only numeric characters
例如%[0123456789]或%[0-9]//仅将数字字符作为字符串读取
%[^character set(denied)]: It is to mean character other than when ^is specified at the beginning of the character set.
%[^character set(denied)]: 表示^字符集开头指定的时候以外的字符。
回答by unwind
Yes, you can scan for a character set. The problem you're seeing is not related to the vertical bar, it's the fact that a string stops at the first whitespace character, i.e. the space between "TEST"and "ME|".
是的,您可以扫描字符集。看到的是不相关的竖线的问题你,这是一个事实,即一个字符串,停在第一个空格字符,即之间的空间"TEST"和"ME|"。
So, do something like:
因此,请执行以下操作:
if(scanf("%7[^|] | %7[^|]", a, b) == 2)
{
a[7] = b[7] = 'char a[200], b[200];
scanf ("%[^|]| %[^\n]", a, b); // Use it exactly
printf ("a = %s\nb = %s\n", a, b);
';
printf("got '%s' and '%s'\n", a, b);
}
See the manual page for scanf()for details on the [conversion specifier.
有关转换说明符的详细信息,请参阅手册页scanf()[。
回答by CancerSoftware
This one should work.
这个应该有效。
first string is this | 2nd is this
a = first string is this
b = 2nd is this
no space|between bar
a = no space
b = between bar
Meaning of this formatting. I seperate the format string into 3 parts and explain.
这种格式的含义。我将格式字符串分成 3 部分并进行解释。
"%[^|]" - Scan everything into 1st string, until the bar character('|') appears.
"%[^|]" - 将所有内容扫描到第一个字符串中,直到出现条形字符 ('|')。
"| " - Read the '|' and ignore it. Read all white space characters and ignore them.
“|” - 阅读“|” 并忽略它。读取所有空白字符并忽略它们。
"%[\n]" - Read remainder of the line into the 2nd string.
"%[\n]" - 将行的其余部分读入第二个字符串。
Test case
测试用例
first_string contains leading spaces from given input string
second_string contains actual data without leading spaces.
回答by Praveen
Leading spaces can be truncated by using extra local variable to store leading spaces.
可以通过使用额外的局部变量来存储前导空格来截断前导空格。
%[ ] needs to be mentioned in scanf to store leading spaces
"%[ ]%[^\n]",first_string,second_string , mentioned scanf format specifier is to read two strings .
%[ ] 需要在 scanf 中提及以存储前导空格
"%[ ]%[^\n]",first_string,second_string ,提到 scanf 格式说明符是读取两个字符串。
int main()
{
char lVar[30];
char lPlaceHolder[30];
printf("\n Enter any string with leading spaces : ");
memset(lVar,'char s1[] = "FOO | BAR";
char s2[] = "FOO BAR |";
void print_sep(char *in)
{
char *endp;
char *sep = strtok_r(in, "|", &endp);
printf("%s\n", sep);
if (sep = strtok_r(NULL, "|", &endp))
printf("%s\n", sep);
}
print_sep(s1);
print_sep(s2);
',30);
memset(lPlaceHolder,'##代码##',30);
scanf("%[ ]%[^\n]",lPlaceHolder,lVar);
printf("\n lPlaceHolder is :%s:\n",lPlaceHolder);
printf("\n lVar is :%s:\n",lVar);
return(0);
}
Following is the sample code
以下是示例代码
##代码##Input:
输入:
" hello world"
“ 你好,世界”
Output:
输出:
lPlaceHolder is : :
lVar is :hello world:
lPlaceHolder 是 ::
lVar 是 :hello world:
Note: Space not displayed properly for lPlaceHolder after uploading to stackover flow website
注意:上传到 stackover Flow 网站后,lPlaceHolder 的空间显示不正确
回答by Praveen
I'd say instead of messing with scanf(), try using saner functions - those that work as per the (intuitive) expectations:
我想说,不要乱用scanf(),而是尝试使用更明智的函数 - 那些按照(直觉)期望工作的函数:

