Why can std::copy_n not copy continuously between each call - c++11

I got to find std::copy_n with a behavior like this:
stringstream ss;
ss.str("abcdefghij");
string str;
str.resize(10);
std::copy_n(istreambuf_iterator<char>(ss), 5, str.begin());
cout << str << endl;
std::copy_n(istreambuf_iterator<char>(ss), 5, str.begin());
cout << str << endl;
It seems that what I got printed is abcde\n efghij".
Is this the correct behavior of iterator related operations ?

The shown usage of std::copy_n with the arguments given should result in an output
abcde
efghi
To explain the above,
std::copy_n(istreambuf_iterator<char>(ss), 5, str.begin());
copies 5 characters starting at 'a' to the beginning of str. str is now "abcde" followed by 5 default char instances, i.e., null bytes (which aren't printed as the first null byte is interpreted as the end sentinel of the string). The null bytes stem from str.resize(10). After this call, ss points to the position of 'e' in ss. The next, identical call
std::copy_n(istreambuf_iterator<char>(ss), 5, str.begin());
copies 5 characters starting at 'e' to the beginning of str. str is now "efghi" followed by 5 null bytes.
If instead the output
abcde
abcdefghij
is desired, you can change the second invocation of std::copy_n to
std::copy_n(std::next(istreambuf_iterator<char>(ss)), 5, str.begin() + 5);
which copies 5 characters starting at 'f' to str, starting at str's first null byte.

Related

What is the meaning of following line of code in Golang?

var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
how come we are allowed to have :1 in the code above and what is the meaning of that?
asciiSpace is declared an array of uint8 with indexes 0 .. 255 (i.e. the ASCII range), and the values for the indexed elements are set to 1.
The array indexes are given as '\t', '\n' etc. indicating they refer to whitespace characters.
My guess is you misinterpreted the sequence "index : value".
A similar example is given in a (randomly chosen) Go Tutorial.

Capitalize every nth character of each word in a string in Ruby

I need to capitalize every 'nth' character for each word in a string (every multiple of 4-th character in this example, so character 4, 8, 12 etc).
I came up with the code below (not very elegant I know!) but it only works for words which length < 8.
'capitalize every fourth character in this string'.split(' ').map do |word|
word.split('').map.with_index do |l,idx|
idx % 3 == 0 && idx > 0 ? word[idx].upcase : l
end
.join('')
end
.flatten.join(' ')
Anybody could show me how to capitalize every 4th character in words which length > 8?
Thanks!
str = 'capitalize every fourth character in this string'
idx = 0
str.gsub(/./) do |c|
case c
when ' '
idx = 0
c
else
idx += 1
(idx % 4).zero? ? c.upcase : c
end
end
#=> "capItalIze eveRy fouRth chaRactEr in thiS strIng"
As an option, you can just modify the nth character in the string if it exists by accessing the character by index:
'capitalizinga every fourth character in this string'.split(' ').map do |word|
(3..word.length).step(4) do |x|
c = word[x]
word[x] = c.upcase if c
end
word
end.join(' ')
# capItalIzinGa eveRy fouRth chaRactEr in thiS strIng
Here is the method step or Range class is used, so each fourth index could be calculated: 3, 7, 11, etc...
I think the easiest way is to use a regex with substitution:
'capitalize every fourth character in this string'
.gsub(/([\w]{3})(\w)|([\w]{1,3})/) {
"#{$1}#{$2.to_s.upcase}#{$3}"
}
# => capItalIze eveRy fouRth chaRactEr in thiS strIng
This uses 2 alternatives with captured groups - the first alternative matches 4 characters and the second everything with 1 to 3 characters. Group $1 will match exactly three letters and group $2 the fourth letter within a 4-letter block - while group $3 will match remainders of a longer word as well words shorter than 4 characters.
You can then replace group $2 globally with gsub. Also you need to do $2.to_s in case $2 is nil (or catch that scenario with a ternary operator).
You can inspect the regex here and try the code here
> str.split(" ").map{|word|
word.chars.each_with_index{|c,i|
c.upcase! if (i > 0 && (i+1)%4 == 0)}.join}.join(" ")
#=> "capItalIze eveRy fouRth chaRactEr in thiS strIng"
def capitalize_each_nth_char(str, n)
str.chars.each_slice(n).to_a.each { |arr| arr[-1] = arr[-1].upcase if arr.size == n }.join('')
end
Here is the explanation,
str.chars # will give array of characters
str.chars.each_slice(n) # will give an enumerator as, #<Enumerator: ...>
str.chars.each_slice(n).to_a # will give an array of arrays
arr[-1].upcase # it will capitalize the last element i.e. 4th element of each array
if arr.size == n # it will prevent to capitalize last element of sub-array if it's size is less than n(in our case 4)
str.chars.each_slice(n).to_a.each { |arr| arr[-1] = arr[-1].upcase if arr.size == n } # it will give array of subarray where every subarray last element is capital
str.chars.each_slice(n).to_a.each { |arr| arr[-1] = arr[-1].upcase if arr.size == n }.join('') # it will give the final result as, "capItalIze EverY foUrth chaRactEr iN thIs sTrinG"

ruby special match variables confusion

This code produces the expected result:
def test_sub_is_like_find_and_replace
assert_equal "one t-three", "one two-three".sub(/(t\w*)/) { $1[0, 1] }
end
I understand that $1 is a variable for the first match, but I am not clear what the [0,1] is, or why it takes out the last two letters of "two".
This is covered in the String.[] documentation, in particular:
str[start, length] → new_str or nil
So, $1[0, 1] means, "slice the string returning from character at index 0 to index 0 + 1."
The [0,1] can be applied to any string to find 1 character starting at index position 0:
>> "Hello"[0,1]
=> "H"
Just for fun, something other than 0 and 1:
>> "Hello World"[3,5]
=> "lo Wo"
Starts at index position 3, takes 5 characters.
In your case
"two"[0, 1]
you take one character at index 0, namely "t". It looks like it removed the last two characters; in reality it produced only the first.

How to program the below text format logic in ruby to validate a text field

I have a text field where it accepts only the text that satisfies the below criteria:
Text format of the below type where 'A' can be any random alphabets, 'D' is any numerical digit, but last digit is sum of all other digits modulo 10.
AAD-AAA-DDD
for example:
KN3-MNO-41_, this means the last digit is: 3 + 4 + 1 = 8, so it becomes: KN3-MNO-418
HK5-SFO-32_, this means the last digit is: 5 + 3 + 2 = 10, so it becomes HK5-SFO-320
I am in my intial learning of ruby, please help me: so how do I include these checks in the script and validate that the input text meets the criteria.
Thanks
def valid?(w)
w.match(/^[a-z][a-z]\d-[a-z][a-z][a-z]-\d\d\d$/i) and
([2,8,9].sum {|i| w[i].to_i} % 10 == w[10].to_i)
end
Here's a wild whack at it:
REGEX = /^([a-z]{2})(\d)-([a-z]{3})-(\d)(\d)(\d)$/i
STRINGS = %w[
KN3-MNO-418
HK5-SFO-320
KN3-MNO-419
HK5-SFO-321
]
def valid?(str)
chars1, d1, chars2, d2, d3, chksum = REGEX.match(str).captures
([d1, d2, d3].map(&:to_i).inject(:+) % 10) == chksum.to_i
end
STRINGS.each do |s|
puts valid?(s)
end
Running that outputs:
true
true
false
false
For fun and profit you can change the match assignment to:
_, d1, _, d2, d3, chksum = REGEX.match(str).captures
and/or the calculation to:
([d1, d2, d3].inject(0) { |m, s| m += s.to_i } % 10) == chksum.to_i
Now, that's sure to be as bewildering to you as it is to me, so I'll break it down:
/^([a-z]{2})(\d)-([a-z]{3})-(\d)(\d)(\d)$/i means:
Start at the beginning of the string and find two characters between "a".."z", followed by...
A single digit, followed by...
A hyphen, followed by...
Three characters between "a".."z", followed by another hyphen and...
Two separate digits and the checksum digit.
REGEX.match(str).captures matches the pattern to the string. captures returns an array of captured values from the string. "captures" are the parts in the pattern between parenthesis.
The results of captures is assigned to the local variables in parallel. Sweet.
([d1, d2, d3].map(&:to_i).inject(:+) % 10) == chksum.to_i is the part that makes us go "wheeeee!!!":
[d1, d2, d3].map(&:to_i) converts an array of strings to an array of integers...
inject(:+) is Ruby magic for "add all the elements of the array together."...
% 10 is modulo 10. Look up modolo, it's your new friend.
The rest you can figure out.

Fastest way to parse fixed length fields out of a byte array in scala?

In Scala, I receive a UDP message, and end up with a DatagramPacket whose buffer has Array[Byte] containing the message. This message, which is all ASCII characters, is entirely fixed length fields, some of them numbers, other single characters or strings. What is the fastest way to parse these fields out of the message data?
As an example, suppose my message has the following format:
2 bytes - message type, either "AB" or "PQ" or "XY"
1 byte - status, either a, b, c, f, j, r, p or 6
4 bytes - a 4-character name
1 byte - sign for value 1, either space or "-"
6 bytes - integer value 1, in ASCII, with leading spaces, eg. " 1234"
1 byte - sign for value 2
6 bytes - decimal value 2
so a message could look like
ABjTst1 5467- 23.87
Message type "AB", status "j", name "Tst1", value 1 is 5467 and value 2 is -23.87
What I have done so far is get an array message: Array[Byte], and then take slices from it,
such as
val msgType= new String(message.slice(0, 2))
val status = message(2).toChar
val name = new String(message.slice(3, 7))
val val1Sign = message(7).toChar
val val1= (new String(message.slice(8, 14)).trim.toInt * (if (val1Sign == '-') -1 else 1))
val val2Sign = message(14).toChar
val val2= (new String(message.slice(15, 21)).trim.toFloat * (if (val2Sign == '-') -1 else 1))
Of course, reused functionality, like parsing a number, would normally go in a function.
This technique is straightforward, but is there a better way to be doing this if speed is important?
Writing your own byte-array-to-primitive conversions would improve speed somewhat (if you're really that in need of speed), since it would avoid making an extra String object. Also, rather than slicing the array (which requires you to make another array), you should use the String constructor
String(byte[] bytes, int offset, int length)
which avoids making the extra copy.
I don't have the data to make performance tests, but maybe you have? Did you try pattern matching, with a precompiled pattern?
The numbers in the comment enumerate the opening parens, which correspondend to the groups:
// 12 3 4 5 6 7 8 9 10
val pattern = Pattern.compile ("((AB)|(PQ)|(XY))([abcfjrp6])(.{4})([- ])( {0,6}[0-9]{0,6})([- ])([ 0-9.]{1,6})")
//
def msplit (message: String) = {
val matcher = pattern.matcher (message)
if (matcher.find ())
List (1, 5, 6, 7, 8, 9, 10).foreach (g => println (matcher.group(g)))
}
val s = "ABjTst1 5467- 23.87"
msplit (s)
Pattern/Matcher is of course Javaland - maybe you find a more scala-way-solution with "...".r
Result:
AB
j
Tst1
5467
-
23.87

Resources