Entraides et échanges autour de la technologie Scol - Informations and exchanges on the Scol technology
Vous pouvez changer la langue de l'interface une fois inscrit - You can change the language once registered
You are not logged in.
hello
I am trying to write a comparison operator the long way to read a txt document with strextr.
Here are the contents of the txt file:
name 6.3.1
update 2014-07-31
version d3da4b00
here is how I am trying to get the line whose first word is "version":
fun getversion()=
let strextr _getpack _checkpack "strextr/strextr.txt" -> linelist in
let sizelist linelist -> size in
let nil-> version in
let 0 -> i in
(
while i < size do
(
let nth_list linelist i -> element in
let hd element ->first_word in
(
if ((strcmp "version" first_word) ==0) then nil else
set version = hd tl element;
set i=i+1;
);
);
_showconsole;
_fooS "the version is";
_fooS version;
);;
Instead of returning:
The version is
d3da4b00
in the console, the function is returning
The version is
2014-07-31
so strcmp "version" first_word returns 0 when the first word in a line is "update"
I don't know why....it's something obvious that I'm missing unfortunately.
thx for your help
Offline
Hi,
First, the better way for that is :
fun getversion()=
let strextr _getpack _checkpack "strextr/strextr.txt" -> linelist in
let hd switchstr linelist "version" -> version in
(
_fooS "the version is";
_fooS version;
);;
switchstr : http://www.scolring.org/files/doc_html/switchstr.html
I use "hd switchstr ..." because i want the first word of the result only.
Another way is a recursive function (but in this case switchstr is faster)
fun searchVersion (list)=
if list == nil then
"not found"
else
let hd hd list -> firstWord in
if (!strcmp firstWord "version") then
hd tl hd list // if you wish an explanation tell me
else
searchVersion tl list;;
fun getversion()=
let strextr _getpack _checkpack "strextr/strextr.txt" -> linelist in
let searchVersion linelist -> version in
(
_fooS "the version is";
_fooS version;
);;
Your solution is wrong (right on the principle) because when you check the string you set the variable with the wrong result.
Look at your code :
if ((strcmp "version" first_word) ==0) then // TRUE : first_word = "version"
nil // it is TRUE and you do nothing !!
else // FALSE : first_word is different than "version"
set version = hd tl element; // you set the variable ... So, the last "WRONG" line is "update 2014-07-31" ...
Another remark :
to compare two strings, use the logical negation "!" instead of your "== 0". The result is the same but it's more readable.
if ((strcmp "version" first_word) ==0) then
is the same than
if (!strcmp "version" first_word) then
Thus, your function should be :
fun getversion()=
let strextr _getpack _checkpack "strextr/strextr.txt" -> linelist in
let sizelist linelist -> size in
let nil-> version in
let 0 -> i in
(
while i < size do
(
let nth_list linelist i -> element in
let hd element ->first_word in
(
if (!strcmp "version" first_word) then
set version = hd tl element
else
nil;
set i=i+1;
);
);
_fooS "the version is";
_fooS version;
);;
Offline
Thx Iri! So
if ((strcmp "version" first_word) ==0) then nil
Causes the VM to skip the following line
set version = hd tl element;
And the VM jumps to
set i=i+1;
Until i == size?
Offline
The VM skips this line because you wrote
else
if ((strcmp "version" first_word) ==0) then nil else
set version = hd tl element;
In words, this is :
IF the first word is "version" THEN do nothing ELSE set my variable to the second word
Thus, the variable is set ONLY if the first word is NOT "version".
So, with your text :
name 6.3.1
update 2014-07-31
version d3da4b00
At the first loop, the line is :
name 6.3.1
"name" is not "version", so the VM skips to ELSE : set version = "6.3.1" !!
At the second loop, the line becomes :
update 2014-07-31
"update" is not "version", so the VM skips to ELSE : set version = "2014-07-31" !!
At the third loop, the line is :
version d3da4b00
"version" = "version", so the VM does nothing (your nil statment). So, "set version" keep the previous value.
_fooS "the version is";
_fooS version;
version is "2014-07-31", so "2014-07-31" is displayed !
Offline
thx, I think I understand (most) of your explanations. fwiw, this works too:
fun getversion()=
let strextr _getpack _checkpack "strextr/strextr.txt" -> linelist in
let sizelist linelist -> size in
let nil-> version in
let 0 -> i in
(
while (i < size) && (version == nil) do
(
let nth_list linelist i -> element in
let hd element ->first_word in
(
// else if ((strfindi "idlex_5_24cv" message 0) != nil) then
if ((strcmp "version" first_word) ==1) then nil else
set version = hd tl element;
set i=i+1;
);
);
_showconsole;
_fooS "the version is";
_fooS version;
);;
this way, if "version" is not the first word of the list of strings in a line, the vm is forced to look at the following line. once the loop finds a line where the first word is "version", it returns the remainder of the line and and the loop no longer executes since version != nil. So that is the same as writing
(!strcmp firstWord "version")
your first example though is the simplest, thx for letting me know about that function (again, someday I'll know them from memory.) this is a great help in beginning to learn file reading and prepare to parse files in .xml
Offline
if ((strcmp "version" first_word) ==1) then
In this code, it is WRONG and DANGEROUS !
Read the doc about strcmp : http://www.scolring.org/files/doc_html/strcmp.html
strcmp can return 0, 1 or -1.
So, if you want check if a string is equal another one, use ALWAYS :
if (!strcmp anyString "a string") then
// TRUE, they are equal
else
// FALSE, they are NOT equal
or, if you prefer without the negation (the negation of 0 is 1, the negation of 1 is 0) :
if (0 == strcmp anyString "a string") then
// TRUE, they are equal
else
// FALSE, they are NOT equal
Use another way ONLY to know if a string is greater (return 1) or lesser (return -1) than another one.
your first example though is the simplest, thx for letting me know about that function (again, someday I'll know them from memory.) this is a great help in beginning to learn file reading and prepare to parse files in .xml
Yes, my first version is the best and fastest !
fun getversion()=
_fooS hd switchstr strextr _getpack _checkpack "strextr/strextr.txt" "version";;
(it is my previous version in one line only)
To parse a xml file, you are already an API : http://redmine.scolring.org/projects/sx … psxml.html
Offline
so if (strcmp anyString "a string") is 1 or -1, both are the same as: (!strcmp anyString "a string")
Offline
_fooId strcmp "name" "name" ==>> 0 because "name" is the same string than "name". Right ?
_fooId strcmp "name" "version" ==>> -1 because "name" is lesser than "version" (in the alphabetic order, n is lesser than v). Right ?
_fooId strcmp "version" "name" ==>> 1 because "version" is greater than "name" (in the alphabetic order, v is greater than n). Right ?
_fooId !0 ==>> 1 because the negation ( ! exclamation mark) of 0 is 1
_fooId !1 ==>> 0 because the negation of all integer different than 0 is 1
So :
strcmp "name" "name" ==> 0 so, the negation of this expression i.e. !strcmp "name" "name" (exclamation mark following by strcmp "name" "name") is 1. Right ?
When i write :
if A then // blabla else // blabla
implicitely, i wrote : if A == 1 then // blabla else // blabla
Right ?
When i write :
if !A then // blabla else // blabla
implicitely, i wrote :
if A == 0 then // blabla else // blabla
Thus, when i write :
if !strcmp anyString "a string" then // EQUAL else // NOT EQUAL
I'm certain that anyString is strictly equal at "a string" because :
- the negation of strcmp anyString "a string" is 1 so anyString "a string" returns 0.
The doc is clear : strcmp returns 0 only if the two strings are equals.
so if (strcmp anyString "a string") is 1 or -1, both are the same as: (!strcmp anyString "a string")
So, wrong.
Offline
Thx for the detailed reply....at the moment I feel a bit but I think I'll figure it out.
Last edited by hebdemnobad (17-Oct-2014 22:26:01)
Offline
I think I get it....I had forgotten that strcmp returns 0 when the strings are equal but had thought they return 1 when they are equal, so I had it backwards, what I should have said was. in my coding I've usually used 1 for true and 0 for false in setting interger flags in javascript.
so...
if (strcmp anyString "a string") is 1 or -1, both are the same as: (strcmp anyString "a string")
that is correct, no?
Offline
to simplify just take the habbit to use
(!strcmp A B) to check if a string is equal
and (strcmp A B) to check if they are different
Offline
It's all JavaScript's fault..http://stackoverflow.com/questions/12236271/is-true-1-and-false-0-in-javascript.
Offline
Offline
you are right I was confusing string comparison with Boolean values in javascript where true == 1 and false == 0.
Last edited by hebdemnobad (18-Oct-2014 12:10:59)
Offline
Offline