You've missed the point of how Fscanln is *supposed* to be different to 
Fscan.

Fscanln is when you want to scan *the entire line* in one go, and you know 
in advance exactly the right number of placeholders to capture.  If there 
is extra data on the line after these placeholders, then an error is 
returned. That is: it does the checking for spurious trailing junk for you. 
(If there are insufficient columns then it treats the last ones as empty).

In other words, to take your example number 2: Fscanln(in, &a) is 
*supposed* to return an error with the given input. If you don't know how 
many items to expect in the line, then Fscanln is not what you should be 
using.

On Saturday, 8 February 2025 at 21:39:01 UTC Ivan Burak wrote:

> The correct documentation for current Fscanln() behavior shoud be like this
> Fscanln scans text read from r, storing successive space-separated values 
> into successive arguments. It stops scanning at a newline and after the 
> final item there must be a newline or EOF. If number of arguments  for 
> scanning into is less than the number of values in a text, err will be 
> reported.
> So every time it needs to know the real number of values in a scanning 
> text, not good limitation for real programming.
>
> Another way is to fix some code for Fscanln(). 
> The fix might be as follows
>
> [image: Fscan1.png]
> [image: Fscan2.png]
>
> ------------------------------------------------------------------------------------------------------
> To see the code pls go to  https://go.dev/play/p/-LQhT0zK9_N
> With code changes Fscanln() works without char eating (it was tested 
> locally), the number of values in a scanning text and arguments for 
> scanning into could be different. 
> scan_test.go falls on 2 functions, but the reason is behavior changes for 
> Fscanln(). 
>
>
>
> *The result of code execution*
> [image: Fscan3.png]
>
>
> On Friday, January 31, 2025 at 6:53:11 PM UTC+3 tapi...@gmail.com wrote:
>
>> The documents are too simple to explain clearly on anything.
>> Besides the eating/chomping behavior, does an item include the 
>> space/newline following it?
>> Either answer will not satisfy the behavior of the following code,
>> by either answer, there should one case reports an error.
>>
>> https://go.dev/play/p/XQFwxxiz2NA
>>
>> package main
>>
>> import "fmt"
>> import "strings"
>>
>> func main() {
>> {
>> var r = strings.NewReader("xxx yyy\n")
>> var x, y string
>> n, err := fmt.Fscanln(r, &x, &y)
>> fmt.Println(n, err, x, y, len(y)) // 2 <nil> xxx yyy 3
>> }
>> {
>> var r = strings.NewReader("xxx yyy \n")
>> var x, y string
>> n, err := fmt.Fscanln(r, &x, &y)
>> fmt.Println(n, err, x, y, len(y)) // 2 <nil> xxx yyy 3
>> }
>> }
>>
>>
>>
>> On Friday, January 31, 2025 at 4:11:48 AM UTC+8 Brian Candler wrote:
>>
>>> I guess not, but since it uses a plain io.Reader which doesn't support 
>>> peek or pushback, I can't think of any other behavior which is possible.
>>>
>>> On Thursday, 30 January 2025 at 19:27:51 UTC tapi...@gmail.com wrote:
>>>
>>>> On Tuesday, January 28, 2025 at 7:07:15 PM UTC+8 Brian Candler wrote:
>>>>
>>>> > The documentation tells that Fscanln() is similar to Fscan(), my test 
>>>> shows that it isn't true for some cases. 
>>>>
>>>> "similar" does not mean "the same as".
>>>>
>>>> Fscanln chomps the fields given, then chomps the next character. If the 
>>>> next character is newline, it's happy. If the next character is not a 
>>>> newline, then it's unhappy and returns an error. At this point, you know 
>>>> the input was bad.
>>>>
>>>> No guarantees are made about the state of the input after an error, and 
>>>> as you've found, the next character (which *should* have been a newline) 
>>>> has been chomped.
>>>>
>>>>
>>>> It looks the eating/chomping behavior is not well documented.
>>>>  
>>>>
>>>>
>>>> On Tuesday, 28 January 2025 at 10:07:28 UTC Ivan Burak wrote:
>>>>
>>>>   Hi Howard
>>>>
>>>> Thank you for the answer.
>>>>
>>>> My data is easier, it contains only 2 lines:
>>>> Go version go1.22.11 windows/amd64
>>>> Build simple, secure, scalable systems with Go
>>>>
>>>> I did some tests and to speedup coding decided to use Fscanln().
>>>> I don't use this function in real programming, it's too slow.
>>>> There are many ways to parse texts in Golang that fast and stable.
>>>>
>>>> My test algorithm didn't work, and when I realized what the reason was, 
>>>> I was just surprised.
>>>> The documentation tells that Fscanln() is similar to Fscan(), my test 
>>>> shows that it isn't true for some cases. 
>>>> In my opinion the documentation or the function should be corrected. 
>>>> That's it.  :)
>>>>
>>>> >> fmt.Fscanln(in2,&one,&two,&three,&four)
>>>> That works but you know in our profession, usually we don't know the 
>>>> exact amount of data being processed 
>>>> (number of tokens, records, data volumes etc.), so we have to code 
>>>> based on estimates n, n^2, n^3 ... and we don't know the real n.
>>>>
>>>> thanks
>>>> ivan
>>>>
>>>> On Monday, January 27, 2025 at 11:29:32 PM UTC+3 Howard C. Shaw III 
>>>> wrote:
>>>>
>>>> In your example, you are repeatedly reading one 'item' from the line. 
>>>> This is the source of the confusion, as this is not how Fscanln works - 
>>>> when you do this, *each* item is the documented 'final item' after which 
>>>> there must be a newline.
>>>>
>>>> That is, your data would look more like this:
>>>> space separated column headers
>>>> first second third last
>>>> some data with the
>>>> same pattern of columns
>>>>
>>>> and your read would be pulling all of those items from one line:
>>>> fmt.Fscanln(in2,&one,&two,&three,&four)
>>>>
>>>> It is expected/designed to read one line of data at a time, and for you 
>>>> to know in advance the number of items in the line, and to expect to 
>>>> receive an error if they don't match. It is also expected that each column 
>>>> will have a consistent datatype, and for that to match the types of your 
>>>> parameters, and to error if the data can't be parsed.
>>>>
>>>> For parsing arbitrary string data, you might be better off just using 
>>>> bufio.Scanner with bufio.ScanWords.
>>>>
>>>>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/golang-nuts/4bfa69ba-29f7-4738-a59f-39e794cc850cn%40googlegroups.com.

Reply via email to