我需要 fscanf 参数的解释 [英] I need a explanation of fscanf parameter

查看:66
本文介绍了我需要 fscanf 参数的解释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我需要更好地解释 fscanf 参数.我有以下文本文件

Hello I need a better explanation of the fscanf parameter. I have the following text file

this is line 1
this is line 2
this is line 3
...

读出我所做的

for(int i=0;i<2;++i){
   test[255];
   fscanf(fp,"%[\n]",test);
   printf("%s\n",test);
}

now I get:
this is line 1
this is line 1
with "%[^\n]\n"
I get
this is line 1
this is line 2

现在我将我的陈述分解为我所理解的:% 表示读取它未格式化(%s 会给我一个字符串 %c 单个字符...)[^\n] 直到你得到的东西在这种情况下不匹配换行

now I break my statement apart as far as I understand it: % means read it unformated (%s would give me a string %c single character...) [^\n] until you get something that does not match in this case newline

你能不能更好地解释一下方括号的功能和终止.我阅读了官方解释,但没有完全理解它们.

Could you explain me the function of the square brackets better and the termination. I read the official explanations but don't understand them fully.

扩展 1:我的问题.我知道有更多易于使用的选项来实现我的目标.但我只是尝试了解 fscanf 的语法.

extension 1: of my question. I am aware that there are more easy to use options to achieve my goal. But I just try to understand the syntax of fscanf.

扩展 2:当我理解正确时

extension 2: when I understand it right

fscanf(fp,"%[^\n]%*c",test)

一直读到换行符并跳过下一个换行符.按照这个逻辑 %[^\n] 将是除换行符之外的每个字符.我可以写

reads until newline and skips the next character which IS the newline. Following this logic %[^\n] would be every character except newline. I could write

for(int i=0;i<2;++i){
   test[255];
   fscanf(fp,"%[a-z]",test);
   printf("%s\n",test);
}

我希望得到

this
is

但是我明白了

ٷ�
ٷ�

扩展 3问题不重复scanf() 将换行符留在缓冲区中因为我想阅读完整的一行

extension 3 question is not duplicate to scanf() leaves the new line char in the buffer as i want to read a complete line

推荐答案

使用 scanf 函数系列是对输入流中剩余内容进行说明的练习.格式说明符 %[^\n] 使用 character class(不是 '\n')来读取直到换行符——允许带空格的字符串输入.字符类(例如 [...])匹配括号内的内容,'^' 作为字符中的第一个字符class 反转匹配.转换完成后,'\n' 行尾会留在输入缓冲区中.

Using the scanf family of functions is an exercise in accounting for what remains in your input stream. The format specifier %[^\n] uses the character class (not a '\n') to read up until the newline -- allowing string input with spaces. A character class (e.g. [...]) matches what is within the brackets, a '^' as the first character in the character class inverts the match. When the conversion is complete, the '\n' line-end is left in the input buffer.

由于字符串转换在遇到换行符时结束,而没有删除保留在输入缓冲区中的 '\n',因此您的下一次读取尝试将终止而没有读取任何字符(输入失败)),test 的值保持不变(保持第一行的值),所以当你再次打印时,你得到同样的东西.

Since the string conversion ends when it encounters a newline, without removing the '\n' that remains in the input buffer, your next attempt to read terminates without any characters being read (an input failure), the value of test is left unchanged (holding the value of the first line) so when you print it again, you get the same thing.

来自man 3 scanf

s  Matches a sequence of non-white-space characters; ...  The input string stops
   at white space or at the maximum field width, whichever occurs first.

[  Matches a nonempty sequence of characters from the specified set of accepted 
    characters; ... The usual skip of leading white space is suppressed.

当您更改格式字符串以包含换行符 ("%[^\n]\n") 时,您只是删除了剩余的换行符.因此,您下次尝试阅读时会看到第二行的第一个字符,并且读取正确.您还可以使用 ("%[^\n]%*c") 和 '*'(赋值抑制运算符)来读取和丢弃后面的下一个字符字符类.

When you change the format string to include a newline ("%[^\n]\n"), you are simply removing the newline that remains. So your next attempt to read sees the first character of the second line and it reads correctly. You could also use ("%[^\n]%*c") using '*', the assignment suppression operator, to read and discard the next character following the character class.

这个陷阱(没有考虑保留在输入缓冲区中的字符)是鼓励新 C 程序员使用 fgets(或 POSIX getline)的主要原因之一) 用于面向行的输入,因为这两个函数都会读取(并包含)它们填充的缓冲区中的换行符 - 消除了使其未读的可能性 - 只是等待为您的下一次读取造成问题.

This pitfall (failing to account for characters that remain in the input buffer) is one of the primary reasons new C programmers are encouraged to use fgets (or POSIX getline) for line-oriented input as both functions read up to (and include) the newline in the buffers they fill -- eliminating the potential for leaving it unread -- just waiting to cause problems for your next read.

这篇关于我需要 fscanf 参数的解释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆