Odd behavior by strmid()

Posted By: Morris

Odd behavior by strmid() - 08/26/20 11:53

strmid() does not return what I would sensibly expect when running into the end of the string; instead, it returns the last character before the end (going back before the 'first' parameter). This is observed with Zorro 2.25.7. Code in point:

Code
void main() {
    string test = "abc\0def";
    printf("\ntest='%s'", test);      // Prints 'abc' -- as expected

    string mid = strmid(test, 0, 2);
    printf("\nmid='%s'", mid);        // Prints 'ab' -- as expected

    string mid = strmid(test, 2, 2);
    printf("\nmid='%s'", mid);        // Prints 'c' -- as expected

    string mid = strmid(test, 3, 2);
    printf("\nmid='%s'", mid);        // Prints 'c' -- that appears wrong. Should yield an empty string

    string mid = strmid(test, 4, 2);
    printf("\nmid='%s'", mid);        // Prints 'c' -- that definitely appears wrong. Should print an empty string or 'de'
}

The real life case for this involved parsing a configuration file, where running mid on the end of the string should have returned just '\0'.

Am I wrong in assuming this might be a bug?
Posted By: danatrader

Re: Odd behavior by strmid() - 08/27/20 09:46


If

string test = "abc\0def";
printf("\ntest='%s'", test); // Prints 'abc' -- as expected

and you do strmid on "test" -->> see manual:

count - number of characters in the copy; 1000 characters maximum. If count exceeds the length of str, it is copied until the end.

important here: If count exceeds the length of str, it is copied until the end.


So "test" is abc which is
012
abc

this exceeds the count:

tring mid = strmid(test, 3, 2);
printf("\nmid='%s'", mid); // Prints 'c' -- that appears wrong. Should yield an empty string

string mid = strmid(test, 4, 2);
printf("\nmid='%s'", mid); // Prints 'c' -- that definitely appears wrong. Should print an empty string or 'de'
Posted By: Morris

Re: Odd behavior by strmid() - 08/28/20 08:32

danatrader, thanks for your reply. I'm not sure I follow, though. I think you are saying strmid() behaves as designed, right?

"If count exceeds the length of str, it is copied until the end" => That means strmid() returns the entire rest of the string until the end. But that is not the issue here. As you pointed out, count (=2 in each example) is in fact *less* than the length of str.

In my last two examples, what is returned is one resp. two characters *prior* to the one pointed to by first. This is inconsistent with the description in the manual and with strmid()'s behavior in adjacent cases.
Posted By: danatrader

Re: Odd behavior by strmid() - 08/28/20 08:51

string base = strmid(Asset, 0, 3);

This works in my script, but I will verify, cause don't want some odd behaviour to crash my script.
Posted By: Morris

Re: Odd behavior by strmid() - 08/28/20 09:07

danatrader, thanks again. The signature for strmid is strmid(str, first, count). So in your example, first (3) matched (not exceeded) the length of str, and count (2) did not. So I don't think this is pertinent to the case in the manual where count exceeds len(str).

> string mid = strmid(test, 3, 2);
> 0123 (3 exceeds) but you want two characters, so since 3 exceeds, the complete is returned and the 2 is pulled

By your logic, strmid(test, 3, 1) would return the second character in test ("the 1 is pulled"), but it doesn't; it still returns 'c'.

I would expect strmid to return count characters starting with first (like it says in the manual, by the way). And if count is more than what's remaining after first, the whole remainder is returned (same behavior as, e.g., MID() in Excel). There is no reason, at least that I can see, why strmid would return any character *before* first.
© 2024 lite-C Forums