Uninitialized string offset while calculating string length without using strlen() - php

<?php
$a = "Hello World I am Neha Singh Chouhan";
$length = 0;
do {
$length++;
}
while ($a[$length] != null);
echo "Length = ".$length."<br/>";
for ($i = $length - 1; $i >= 0; $i--) {
echo $a[$i];
}
?>
tried to calculate the string length without using inbuilt function strlen().
the output was
Notice: Uninitialized string offset: 35 in C:\xampp\htdocs\Neha\ProgramsFromClass\10_reverse_string.php on line 7
Length = 35
nahuohC hgniS aheN ma I dlroW olleH
What causes the notice and how can i get rid of it?

Your loop is incorrect. You increment your $length BEFORE you start using it, and run off the end of the string. Therefore you're testing offsets, 1,2,3,...n, where n is one past the end of the string.
And since you're testing for a non-existent "array" key, no matter how you look at it, you'll always get the error, even after you swap the loop types.
do/while is NOT the loop to use for this. You want a plain while loop, and use isset() instead:
$length = 0;
while(isset($a[$length])) { $length++; }

Related

Change "oo" to "00" in a string using some loop

Need to hep to change multiple characters in a string using some loop without built-in functions in PHP.
<?php
$givenString = "School";
$i=0;
while($givenString[$i]){
$i++;
if($givenString[$i] == o){
$givenString[$i] = 0;
}
}
echo $givenString;
?>
Result: Sch0ol
Required Result: Sch00l
Because your loop logic is out of order. Feed in the string "ooooo" and you'll get "o0ooo" out. It skips the first letter because the first thing you do is move the index ahead, and it stops after the first replacement because you're testing the character that you just replaced, and "0" type-juggles to boolean as false.
Move $i++ to the end of the loop and you'll get "00000", but also Warning: Uninitialized string offset 6. This is because you're relying on the error to break the loop. You need to bound the loop on the length of the string, not the content.
So:
$givenString = "oooooo";
$i=0;
$c=strlen($givenString);
while($i<$c){
if($givenString[$i] == 'o'){
$givenString[$i] = 0;
}
$i++;
}
echo $givenString;
or we can condense that with for loop:
$givenString = "oooooo";
for( $i=0, $c=strlen($givenString); $i<$c; $i++ ){
if($givenString[$i] == 'o'){
$givenString[$i] = 0;
}
}
echo $givenString;
For completeness, the un-quoted o in your post only works because pre-8.0 PHP assumed that unquoted constants were just "oopsies" meant to be strings and replaced them with their string equivalent, issuing a Notice like Notice: Use of undefined constant o - assumed 'o', which can potentially have serious side-effects.
This error also indicates that you're using a version of PHP that is no longer supported, and you should ensure that you are writing code on a supported version.
In your current code, you are replacing all o to 0 which is off-track with respect to replacing oo to 00 and also skipping the current o at hand doesn't make sense. Also, as already pointed out, matching a string with a string is better than comparing with just o directly.
You can instead match o with o and check if string contained a previous o or not. If it did, mark both previous and current location as 0, or else, leave it as is. Since you didn't wish to use inbuilt functions, you can use null-coalescing operator(??) to check with the length of the string as well.
<?php
function modify($string){
for($i = 1; ($string[$i] ?? false) !== false; ++$i){
if($string[ $i ] === 'o' && $string[$i - 1] === 'o'){
$string[ $i ] = $string[$i - 1] = '0';
}
}
return $string;
}
Online Demo

Why does this function generate an uninitialized string offset notice?

I'm having this error when I run my program:
Notice: Uninitialized string offset: 7 in C:\xampp\htdocs\demo\str_rev.php on line 21
What causes that?
<?php
//strrev($arg);
/*$str = "ademola";
echo strrev("$str");
*/
function reverse_String($str){
$i = 0;
while(!empty($str[$i])){
echo $str[$i];
$i++;
}
for($r = $i; $r > -1; $r--){
$reverse = $str[$r];
echo $reverse;
}
}
reverse_String("Ademola");
?>
Output:
Ademola
Notice: Uninitialized string offset: 7 in C:\xampp\htdocs\demo\str_rev.php on line 21
alomedA
The $i++; in your first while loop increments $i to 7 in its last iteration. The condition !empty($str[$i]) is no longer satisfied, so the loop does not execute again, but $i is still 7 when the next loop starts, which is an index beyond the end of the string.
There are various ways to fix this, a simple way is to subtract 1 from the counter when you define your second loop to set $r to the index of the last character in the string.
for($r = $i - 1; $r > -1; $r--){ ...
As mentioned by Don't Panic there are many ways to fix this,
you can use isset as:-
for($r = $i; $r > -1; $r--){
if(isset($str[$r])) {
$reverse = $str[$r];
echo $reverse;
}
}
Or to reverse the string you can simply use the php's built in function (strrev)
echo strrev('Ademola')

How to add <br> in string with substr()

For the following code :
<?php
$word = 'SEKISUI';
// echo substr($word,0,-6)."<br>";
$length = (strlen($word)+1)-14;
$urut = 0;
for($i=$length;$i<1;$i++){
echo substr($word,$urut,$i).'<br>';
// echo $urut."-".$i."-".'<br>'; // Check Value
$urut++;
}
?>
Result :
S
E
K
I
S
U
why the letter "i" doesn't appear?
what is wrong with my code?
The result should look like:
S
E
K
I
S
U
I
Thank you for your attention...
I don't know if you NEED to use a 'for loop', but there is a better way to split a string into single characters.
Once you have the array you can do any operation to it, also join() the items in the array with a "\< br>" separator.
Try the following:
$word = 'SEKISUI';
$result = str_split($word);
$altogether = join("<br>",$result);
Not sure why you like the subtracting the length and not deal with positive numbers as much as possible.
In the syntax of substr(string,start,length),
Optional. Specifies the length of the returned string. Default is to
the end of the string. A positive number - The length to be returned
from the start parameter Negative number - The length to be returned
from the end of the string
So essentially your pointer on the end character is nevel counted.
if you run echo substr($word,0,-1)."<br>";, you will not get the end character as it is place of the start for the negative substr.
However, changing the substr length to 1 will give a valid string and not null or empty string
$word = 'SEKISUI';
// echo substr($word,0,-6)."<br>";
$length = (strlen($word)+1)-14;
$urut = 0;
for($i=$length;$i<1;$i++){
echo substr($word,$urut,1).'<br>';
// echo $urut."-".$i."-".'<br>'; // Check Value
$urut++;
}
However, I would prefer this approach, as this is much simpler.
$word = 'SEKISUI';
//echo substr($word,1,1)."<br>";
$length = strlen($word);
$urut = 0;
for($i = $urut; $i <= $length; $i++){
echo substr($word,$i,1).'<br>';
}

Uninitialized string offset notice when generating random GUID

I have a code that causes the above error to show up repeatedly in my error log, how can I correct it?
public function generate_guid() {
//you can change the length of the autogenerated guid here
//i choose 4 because with 26 possible characters that still gives 456.976 possibilities, if you include numbers ( add 0123456789) to the possible characters you will get 1.679.616 combinations
$length = 4;
//charachters used for string generation
$characters = 'abcdefghijklmnopqrstuvwxyz';
$string = '';
for ($p = 0; $p < $length; $p++) {
$string .= $characters[mt_rand(0, strlen($characters))]; <<-- this is line 92
}
return $string;
}
The problem is that mt_rand(0, strlen($characters)) will generate numbers up to the strings length - but as the string offsets start with 0 the maximum offset is the length minus one. So correct would be mt_rand(0, strlen($characters) - 1).
By the way, I would recommend using a characters array generated by range('a', 'z') (so you don't have to type it out) and getting an element using array_rand.

PHP loop thru hex numbers from a form POST always gives the first number as 0. why?

i have a form with two text fields, "from" and "to."
when i enter values such as "100000" and "10000F" and do a for loop, it always comes out like:
0 100001 100002 100003 100004 100005 100006 100007 100008 100009 10000a 10000b 10000c 10000d 10000e 10000f
if i plug in the range for the loop manually, i get:
100000 100001 100002 100003 100004 100005 100006 100007 100008 100009 10000a 10000b 10000c 10000d 10000e 10000f
using:
for ($i = '0x'.$_POST['from']; $i <= '0x'.$_POST['to']; $i++) { print dechex($i)."\n"; }
versus:
for ($i = 0x100000; $i <= 0x10000F; $i++) { print dechex($i)."\n"; }
if anyone knows what i am doing wrong here, please let me know.
i have also tried tried adding the "0x" to the numbers via the form with the same results.
thanks!
While $i++ is converting $i to a number, this doesn't run until after the first loop. Apparently dechex doesn't try to interpret strings as numbers and just barfs.
To force conversion, prefix the string expression with a +:
for ($i = +('0x'.$_POST['from']); $i <= '0x'.$_POST['to']; $i++) {
print dechex($i)."\n";
}
Tested and working on PHP 5.2.6.
(Note that casting does not work! (int)('0x100000') returns 0.)
You should use intval() to convert a hex string to a number. dechex() will take the number and turn it back into a hex string:
$from = intval('100001', 16);
$to = intval('10000f', 16);
for ($i = $from; $i <= $to; $i++) {
print dechex($i) . "\n";
}
'0x'.$_POST['from']; is a string $i = 0x100000 is a number
Your first iteration will cast the string value to a number using standard PHP casting (as an integer value to the first non-numeric character, which is the 'x' giving a start value of 0)
You can also do
for ($i = intval('0x'.$_POST['from'], 0); $i <= intval('0x'.$_POST['to'], 0); $i++) { print dechex($i)."\n"; }
You need to convert your hex string to an actual integer first. Something like this function does.
Otherwise, PHP will handle it as a string.

Categories