• strspn()

    From Michael Sanders@3:633/10 to All on Fri Nov 21 18:41:01 2025
    So strspn, perfect for what I need!

    before:

    int ok = 1;

    if (strlen(colorSpec) == 4) {
    for (int i = 0; i < 4; i++) {
    char c = colorSpec[i];
    if (c < '1' || c > '8') { ok = 0; break; }
    }
    } else ok = 0;

    after:

    strspn() returns the length of the leading substring
    consisting ONLY of characters in the allowed set...

    if (strlen(colorSpec) != 4 && strspn(colorSpec, "12345678") = 4) FAIL;

    --
    :wq
    Mike Sanders

    --- PyGate Linux v1.5.1
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael Sanders@3:633/10 to All on Fri Nov 21 18:42:16 2025
    On Fri, 21 Nov 2025 18:41:01 -0000 (UTC), Michael Sanders wrote:

    if (strlen(colorSpec) != 4 && strspn(colorSpec, "12345678") = 4) FAIL;

    Should instead be:

    if (strlen(colorSpec) != 4 && strspn(colorSpec, "12345678") != 4) FAIL;

    --
    :wq
    Mike Sanders

    --- PyGate Linux v1.5.1
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael Sanders@3:633/10 to All on Fri Nov 21 19:06:18 2025
    On Fri, 21 Nov 2025 18:41:01 -0000 (UTC), Michael Sanders wrote:

    So strspn, perfect for what I need!

    before:

    int ok = 1;

    if (strlen(colorSpec) == 4) {
    for (int i = 0; i < 4; i++) {
    char c = colorSpec[i];
    if (c < '1' || c > '8') { ok = 0; break; }
    }
    } else ok = 0;

    after:

    strspn() returns the length of the leading substring
    consisting ONLY of characters in the allowed set...

    if (strlen(colorSpec) != 4 && strspn(colorSpec, "12345678") = 4) FAIL;

    Actually is should be:

    if (strlen(colorSpec) != 4 || strspn(colorSpec, "12345678") != 4) FAIL;

    Excuse the extra posts, got excited.

    --
    :wq
    Mike Sanders

    --- PyGate Linux v1.5.1
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Sat Nov 22 00:04:24 2025
    On 21/11/2025 18:41, Michael Sanders wrote:
    So strspn, perfect for what I need!

    before:

    int ok = 1;

    if (strlen(colorSpec) == 4) {
    for (int i = 0; i < 4; i++) {
    char c = colorSpec[i];
    if (c < '1' || c > '8') { ok = 0; break; }
    }
    } else ok = 0;

    after:

    strspn() returns the length of the leading substring
    consisting ONLY of characters in the allowed set...

    if (strlen(colorSpec) != 4 && strspn(colorSpec, "12345678") = 4) FAIL;


    Performance probably isn't critical in your use-case, but the solution
    using 'strspn' was three times as slow as doing the explicit code.

    (Test string was a fixed "8725" and tested 100M times.)

    This is not surprising since strspn doesn't know that the substring is
    ordered so doesn't need to test every character of the input string
    against every every character of the substring, at least while there is
    a match.

    --- PyGate Linux v1.5.1
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael Sanders@3:633/10 to All on Sat Nov 22 00:56:06 2025
    On Sat, 22 Nov 2025 00:04:24 +0000, bart wrote:

    Performance probably isn't critical in your use-case, but the solution
    using 'strspn' was three times as slow as doing the explicit code.

    (Test string was a fixed "8725" and tested 100M times.)

    This is not surprising since strspn doesn't know that the substring is ordered so doesn't need to test every character of the input string
    against every every character of the substring, at least while there is
    a match.

    I don't doubt it bart. Where as my loop was custom built for that particular condition, strspn() has to be alot more generic & thus slower. But still its
    a nifty function in concept no?

    --
    :wq
    Mike Sanders

    --- PyGate Linux v1.5.1
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Ben Bacarisse@3:633/10 to All on Sat Nov 22 02:41:11 2025
    Michael Sanders <porkchop@invalid.foo> writes:

    So strspn, perfect for what I need!

    before:

    int ok = 1;

    if (strlen(colorSpec) == 4) {
    for (int i = 0; i < 4; i++) {
    char c = colorSpec[i];
    if (c < '1' || c > '8') { ok = 0; break; }
    }
    } else ok = 0;

    There's no need for the strlen test:

    int i = 0;
    while (i < 4 && colorSpec[i] >= '1' && colorSpec[i] <= '8') i++;
    int ok = i == 4 && colorSpec[i] == 0;

    after:

    strspn() returns the length of the leading substring
    consisting ONLY of characters in the allowed set...

    if (strlen(colorSpec) != 4 && strspn(colorSpec, "12345678") = 4) FAIL;

    Hmm... don't you mean

    if (strlen(colorSpec) != 4 || strspn(colorSpec, "12345678") != 4) FAIL;

    You could also write the positive test explicitly like this, again
    without strlen:

    static bool in_range(char c) { return c >= '1' && c <= '8'; }
    ...
    in_range(colorSpec[0]) && in_range(colorSpec[1]) &&
    in_range(colorSpec[2]) && in_range(colorSpec[3]) &&
    colorSpec[4] == 0

    --
    Ben.

    --- PyGate Linux v1.5.1
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Ben Bacarisse@3:633/10 to All on Sat Nov 22 02:42:43 2025
    Michael Sanders <porkchop@invalid.foo> writes:

    On Fri, 21 Nov 2025 18:41:01 -0000 (UTC), Michael Sanders wrote:

    So strspn, perfect for what I need!

    before:

    int ok = 1;

    if (strlen(colorSpec) == 4) {
    for (int i = 0; i < 4; i++) {
    char c = colorSpec[i];
    if (c < '1' || c > '8') { ok = 0; break; }
    }
    } else ok = 0;

    after:

    strspn() returns the length of the leading substring
    consisting ONLY of characters in the allowed set...

    if (strlen(colorSpec) != 4 && strspn(colorSpec, "12345678") = 4) FAIL;

    Actually is should be:

    if (strlen(colorSpec) != 4 || strspn(colorSpec, "12345678") != 4) FAIL;

    Excuse the extra posts, got excited.

    Sorry, I read threads in order so commented on this in my earlier reply.

    --
    Ben.

    --- PyGate Linux v1.5.1
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael Sanders@3:633/10 to All on Sat Nov 22 22:02:17 2025
    On Sat, 22 Nov 2025 02:42:43 +0000, Ben Bacarisse wrote:

    Sorry, I read threads in order so commented on this in my earlier reply.

    No worries. Its all good.

    --
    :wq
    Mike Sanders

    --- PyGate Linux v1.5.1
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael Sanders@3:633/10 to All on Sat Nov 22 22:03:59 2025
    On Sat, 22 Nov 2025 02:41:11 +0000, Ben Bacarisse wrote:

    int i = 0;
    while (i < 4 && colorSpec[i] >= '1' && colorSpec[i] <= '8') i++;
    int ok = i == 4 && colorSpec[i] == 0;

    Nice/clean/succinct.

    --
    :wq
    Mike Sanders

    --- PyGate Linux v1.5.1
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)