sscanf behaviour change
Sandbo
Hi,
I was migrating an instrumental function from Igor 6 (x86) to Igor 8 (x64).
The driver works and I could toggle the device on/off, but some setting can no longer be changed. As it turns out, it seem the sscanf function does not work the same way, kindly correct me if I am wrong.
For example, with the below code
function test()
string ctrlName = "SGS1ExtRef"
variable SGSIndex //S:I used index for a numerical representation, not to be confused with SGSNum which is a string.
sscanf ctrlName, "SGS %f", SGSIndex
print SGSIndex
end
The output of Igor 8.00 gives 0 (wrong)
The output of Igor 6.37 gives 1 (desired)
Maybe I can try another similar function?
It would still be great if sscanf can work again so I don't have to change all the functions related.
I also tried to use the NumberByKey function:
It somehow returned Nan.
August 15, 2018 at 01:50 pm - Permalink
I tested your function in various versions of Igor:
Igor8 on Windows is the outlier. I suspect that this is caused by a change in the Microsoft library that provides sscanf.
I get the same results for "SGS %f" and "SGS%f" (no space).
I will investigate.
Here is a workaround: (Update: This workaround doesn not work in Igor8 on Windows - details to follow.)
String ctrlName = "SGS1ExtRef"
String temp = ctrlName[3,strlen(ctrlName)-1]
Variable SGSIndex
sscanf temp, "%f", SGSIndex
Print SGSIndex
End
August 15, 2018 at 02:18 pm - Permalink
The problem is a subtle change in sscanf between Visual C++ 2013 (used for Igor7) and Visual C++ 2015 (used for Igor8). This function illustrates:
Variable value
String format = "%f"
String text
text = "1E"
sscanf text, format, value
Printf "text=\"%s\", format=\"%s\", V_Flag=%d, value=%g\r", text, format, V_Flag, value
text = "1X"
sscanf text, format, value
Printf "text=\"%s\", format=\"%s\", V_Flag=%d, value=%g\r", text, format, V_Flag, value
End
sscanf is trying to find a valid number in "text" to match "%f".
sscanf in VC2013 accepts "1E" as a valid number.
sscanf in VC2015 rejects "1E" as a valid number but accepts "1E0". There is, unfortunately, nothing practical that we can do about this subtle change.
A workaround is to change %f to %d in your original function. Then sscanf in VC2015 will be happy to accept "1" as an integer and will not be put off by the "E" following the "1".
August 15, 2018 at 03:39 pm - Permalink
In reply to The problem is a subtle… by hrodstein
Thanks so much for the prompt reply and detailed explanation, it was easy to change from %f to %d with a replace all in my case.
Everything is now working again.
August 15, 2018 at 03:43 pm - Permalink
I think the change in sscanf behaviour is actually fixing a bug. I found https://sourceware.org/bugzilla/show_bug.cgi?id=12701 where the reporter states a similiar problem in glibc which reamains unsolved.
Compiling the following test program with gcc 6.3 and clang 6.0
gives for clang
and for gcc
So also the FLOSS compilers don't agree here.
The official microsoft documentation says for %f:
where at least I had to read it twice to notice that the last optionally refers to the sign and not to the integer value.
August 16, 2018 at 01:52 am - Permalink