C fscanf - 格式化输入

3
我该如何对格式化的fscanf进行格式化,以便将输入{'name surname','username',points}格式化为不包含撇号的字符串?
fscanf(fp,"{%s %s %d}",name,username,username1);

扫描集合 - % [...] - Jonathan Leffler
1
“不包含撇号的字符串”在命名中有时会包含撇号,因此这是不寻常的。为什么有些人的名字中会有撇号/连字符?(https://www.quora.com/Why-do-some-people-have-an-apostrophe-hyphen-in-their-name) - chux - Reinstate Monica
1个回答

5
这应该可以工作:
fscanf(fp,"{'%[a-zA-Z ]', '%[a-zA-Z ]', %d}",name,username,username1);

1
你可以更简洁地使用%[^'],并允许连字符名称。当然,O'Rourke先生仍然会受到影响,但这是提问者的定义问题。有趣的是,username1是一个指向整数的指针。通常情况下,应该是&username1,但没有变量定义,很难知道哪个是正确的。为了避免缓冲区溢出,最好对读入字符串的字符数进行上限设置(例如%49[^']用于char name[50];)。而且必须测试返回值以确保已读取3个值。 - Jonathan Leffler
@JonathanLeffler - 关于你的评论:”_您可以更简洁地使用 %[^']“。为了简单起见,我尝试了"{'%[^'], '%[^'], %d"(仅匹配一个参数,第一个参数),并尝试了"{'%[^'], '%[a-zA-Z], %d",结果相同。您能否解释一下如何更简洁地使用 %[^'] - ryyker
1
@ryyker:在逗号(两次)之前应该先找到引号:"{'%[^']', '%[^']', %d" - Jonathan Leffler
1
@ryyker:否定的扫描集有点危险——例如,它包括换行符,因此如果数据格式不正确,事情可能会变得非常糟糕,特别是没有长度来保护缓冲区溢出。比如说,使用%49[^'\n]作为扫描集会更安全(假设char name[50];)。最好使用fgets()读取行,然后使用sscanf()解析它;这避免了换行符问题,并允许在数据中出现Mr O'Rourke的名字时重新解析该行。_ [ ...继续... ] _ - Jonathan Leffler
1
你可以更加包容:%49[a-zA-Z -]扫描字母、空格和破折号。如果数据中有P.J. O'Neil先生,将.添加到列表中。请注意,破折号必须单独放在开头或结尾。这样就会导致那些名字带有重音符号的人无法读取(UTF-8会出现额外的问题)。否定的扫描集还允许数字和其他标点符号进入名称字段——这可能是一个重要的问题,也可能不是。垃圾进,垃圾出。 - Jonathan Leffler
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接