in reply to Re^6: Reading into array with sscanf
in thread Reading into array with sscanf

It's the -textvariable. You made a reference to an element of an array and then changed to an entirely different array. Don't do that. It's not the scanf, it's that you used

($c_speed[0], $c_speed[1], $c_speed[2], $c_speed[3]) = sscanf("%d %d % +d %d", $rstring);
If you had used
@c_speed = sscanf("%d %d %d %d", $rstring);
it would have also failed.

Try
@c_speed[0 .. $#c_speed] = split ' ', <$rstring>;
and report back. This should keep your -textvariable reference correct.


Or not. You didn't provide a SSCCE so it's hard to tell...

Replies are listed 'Best First'.
Re^8: Reading into array with sscanf
by colintu (Acolyte) on Jul 16, 2024 at 19:54 UTC
    Thanks. That does indeed work. I think I understand your comment about "You made a reference to an element of an array and then changed to an entirely different array." I think I was creating a new list with a different array inside it. Can you point me to something that explains what your suggested code means? I don't recognise what "@c_speed0 .. $#c_speed" is doing. Unless the last bit is a reference to the last element or maybe the array size, which I think would tell split how many pieces I expect.
      Another perl-minded way to do your scanf function would be
      @array[0..3] = ( $buffer =~ /^(\d+) (\d+) (\d+) (\d+)/ ) or die "Buffer didn't match pattern";
      (In list context, the regex match returns a list of the captures, which you can assign to something. If it fails to match, it returns an empty list. Putting the result of the assignment into scalar context converts to the count of list elements, which is nonzero if it matched and zero if it didn't, giving you a boolean to branch off of)

      Using the regex engine might seem like overkill for this simple case, but in most real-world problems the input has some obstacles you want to work around, and using regular expressions is way easier than dancing around with byte offsets and substr and sscanf.

      For even more advanced parsing, checkout the "\G" and "/gc" features of the regex engine, which allow you to iterate along a string without needing to split out substrings, avoiding copying the data over and over into new variables.

      It's perl's array-slice notation.
      my @array= ( 1, 2, 3, 4 ); say $#array; # 3, the max index of the array say @array[0,2] # slice of (1,3) @array[0..3]= ... # assign to first 4 elements @array[0..$#array] # assign to all existing elements