问题: 我试图使用scanf读取一个单独的字段的句子,所以我很自然地使用scanf的自然特征来忽略这个符号,但它也忽略了所有具有|的符号在它。
代码,简化:
int main(){
char* a=malloc(8);
char* b=malloc(8);
scanf("%s | %s",a,b);
printf("%s %s",a,b);
}
当我尝试输入时:
测试| ME
它按预期工作,但是当我有以下情况时:
测试我|
它自然会读取测试,但忽略了ME |,有什么方法吗?
答案 0 :(得分:16)
scanf("%[^ \t|]%*[ \t|]%[^ \t\n|]", a,b);
printf("%s %s",a,b);
注释:
%*
:忽略此元素。
E.g。 %*s
//跳过阅读本文的文本
%[character set(allow)]
:您指定的只读字符集。
E.g。 %[0123456789]
或%[0-9]
//仅作为字符串读取数字字符
%[^character set(denied)]
:除了在字符集开头指定^
之外的其他字符。
答案 1 :(得分:1)
是的,您可以扫描字符集。您看到的问题与垂直条无关,而是字符串停留在第一个空格字符处,即"TEST"
和"ME|"
之间的空格。
所以,做一些像:
if(scanf("%7[^|] | %7[^|]", a, b) == 2)
{
a[7] = b[7] = '\0';
printf("got '%s' and '%s'\n", a, b);
}
有关[
转化说明符的详细信息,请参阅the manual page for scanf()
。
答案 2 :(得分:0)
这个应该有效。
char a[200], b[200];
scanf ("%[^|]| %[^\n]", a, b); // Use it exactly
printf ("a = %s\nb = %s\n", a, b);
此格式的含义。我将格式字符串分成3部分并解释。
“%[^ |]” - 将所有内容扫描到第一个字符串,直到出现小节字符(“|”)。
“|” - 阅读'|'并忽略它。读取所有空格字符并忽略它们。
“%[\ n]” - 将行的剩余部分读入第二个字符串。
测试用例
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
答案 3 :(得分:0)
我要说的是不要乱用scanf()
,而是尝试使用更健全的功能 - 那些按照(直观)期望工作的功能:
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);
答案 4 :(得分:0)
可以通过使用额外的局部变量来存储前导空格来截断前导空格。
需要在scanf中提及%[]来存储前导空格
“%[]%[^ \ n]”,first_string,second_string,提到的scanf格式说明符是读取两个字符串。
first_string contains leading spaces from given input string
second_string contains actual data without leading spaces.
以下是示例代码
int main()
{
char lVar[30];
char lPlaceHolder[30];
printf("\n Enter any string with leading spaces : ");
memset(lVar,'\0',30);
memset(lPlaceHolder,'\0',30);
scanf("%[ ]%[^\n]",lPlaceHolder,lVar);
printf("\n lPlaceHolder is :%s:\n",lPlaceHolder);
printf("\n lVar is :%s:\n",lVar);
return(0);
}
<强>输入:强>
“你好世界”
<强>输出:强>
lPlaceHolder是::
lVar是:你好世界:
注意:上传到stackover flow网站后,lPlaceHolder的空间显示不正确