>>  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.
Yes, Brain. This means the documentation needs to be changed a bit, like 
the blue text in my previous message.

And of course, my example of the fix is not complete, it lacks something 
like EOL error ("end of line" similar to EOF), but it will another function 
Fscanln_v2    :)


On Sunday, February 9, 2025 at 1:03:28 PM UTC+3 Brian Candler wrote:

> 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/ed0cb40e-e784-4a2a-ad15-80bf812fd5ecn%40googlegroups.com.

Reply via email to