Sorry, i don't frequent the forums very often but your assessment of a for loop is correct. you have an initializer, a test, and an action within a for loop.
I typically like to initialize with a variable. for(i=0; i > 100; i++){} for example will loop until the variable i is greater than 100, carry out any tasks within the loop, and then increment i by one and test again to see if i is greater than 100.
As for reading the data one object at a time, assuming you store them in an array or even using object data storage, you can just get the number of objects in the array and iterate over them, initialize a variable for your data to send at the function level to store it. then send before it reaches 1024 characters in length by checking its length before adding data to it. (alternatively by checking its length + the length of the data to add and seeing if that'll put it above 1024 before sending.)
as for the part about "it's activated on-touch" don't rely on this as a method of checking if someone is in the same region, for a lot of cases in sl it will be true, but if your script runs in a region that has neighboring regions, people in those adjacent regions can still touch the object. which would cause a regionsayto to fail. which is why you'd want a check to determine if they're in the same region before trying to regionsayto. that part is as simple as checking llGetAgentSize within the touched event to determine if they are or aren't.
default {
touch_start(integer touch) {
if(llGetAgentSize(llDetectedKey(0)) != ZERO_VECTOR) {
llRegionSayTo(llDetectedKey(0), 0, "Welcome to the region!");
}
else {
llInstantMessage(llDetectedKey(0), "You're so far away!");
}
}
}