in reply to Re^2: I've muddled my bit and byte formats.
in thread I've muddled my bit and byte formats.

You appear to be saying that substr will return the ASCII value represented by the number contained in the selected byte(s) rather than just a sequence of 8 bits I, the computer program, can manipulate how I choose.

substr knows nothing about ASCII. substr returns a portion of the original string

the only way I know how to address that is to grab the byte containing the bit and then try to look inside that.

That is what you must do, But you didn't do that. You still had a string.

Replies are listed 'Best First'.
Re^4: I've muddled my bit and byte formats.
by murrayn (Sexton) on Oct 17, 2018 at 05:25 UTC

    I think I sort of realized that I didn't have what I thought I had but I don't understand why that is the case.

    I took a substr one byte long from a variable. Why is that a "string" rather than a byte containing a sequence of 8 bits? What, then, is a "string" in Perl?

    Obviously, I'm missing a subtlety here. I understand that a "string" in C is a sequence of characters terminated with a null but I am not aware of a comparable construct in a typeless Perl.

      C lies to you. What you think of as a string in C is actually an array of int1's (eight bit integers). C's "char" is actually "int1", so when you subscript a C "string" you get an integer.

      Think of perl's string as an opaque type. That's why perl has an ord() function and a chr() function, to convert back and forth between string and integer.

      If you want to handle your information like you would in C, convert it to an array of ints, which you can then subscript just like you do in C.

      Here are several ways:

      my @intarray = unpack 'c*', "perl string"; my @intarray = map ord, split //, "perl string";

      Also, if you want to pick the i'th integer value from a perl string, there is

      my $integer = vec "perl string", $i, 8;

      Hope this helps.

      Furthermore, when you were doing (simplified example)

      $something = substr("a string", 4, 1) & 2**3;

      you were really doing

      $something = atoi("r") & 2**3;

      because if one argument to "&" is a number and the other is a string, it converts the other to a number (with an equivalent to C's atoi function).

        Thank you for that explanation. I have been confused about Perl being typeless - it's clever about hiding types from programmers in most cases but not when one gets too deep into bit-level manipulations. I muddled myself but then continued to shift both sides of the puzzle at once.

        And the fact that I know a C string is null-terminated does NOT mean I am anything remotely resembling a C programmer!

      It's a string rather than a integer because substr returns a strings, not integers.

      You say Perl is typeless when the whole issue you're having is that you think that substr returns a value of a different type than it does.


      You seem to claim your approach would work in C, but it wouldn't.

      #include <stdio.h> #include <stdlib.h> #include <string.h> char* substr(const char* src, size_t start, size_t len) { while (start && *src) { ++start; ++src; } char* dst = malloc(len+1); if (!dst) return NULL; dst[len] = 0; return strncpy(dst, src, len); } int main() { const char* s = "\x90"; char* first = substr(s, 0, 1); printf("%02X\n", first); free(first); return 0; }
      Output:
      $ gcc -Wall -Wextra -pedantic -std=c99 a.c -o a && a a.c: In function ‘main’: a.c:22:4: warning: format ‘%X’ expects argument of type ‘unsigned int’ +, but argument 2 has type ‘char *’ [-Wformat=] printf("%02X\n", first); ^ 1E25970

      You need to do something to extract the number from the string: *first (C) or ord($first) (Perl).