PDA

View Full Version : FOR - Bug in PHP?


Moonlight
04-28-2001, 02:28 PM
I have a weird bug in PHP. I'm trying to do the menu displaying :

A | B | C | D | E | F | ... | Z | Other

I have the following code :
for ($char = 'A'; $char <= 'Z'; $char++) {
[nbsp][nbsp][nbsp][nbsp][nbsp]echo &quot;$char | &quot;;
} With the above code, I get a result of :

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | AA | AB | AC | AD | AE | AF | AG | AH | AI | AJ | AK | AL | AM | AN | AO | AP | AQ | AR | AS | AT | AU | AV | AW | AX | AY | AZ | BA | BB | BC | BD | BE | BF | BG | BH | BI | BJ | BK | BL | BM | BN | BO | BP | BQ | BR | BS | BT | BU | BV | BW | BX | BY | BZ | CA | CB | CC | CD | CE | CF | CG | CH | CI | CJ | CK | CL | CM | CN | CO | CP | CQ | CR | CS | CT | CU | CV | CW | CX | CY | CZ | DA | DB | DC | DD | DE | DF | DG | DH | DI | DJ | DK | DL | DM | DN | DO | DP | DQ | DR | DS | DT | DU | DV | DW | DX | DY | DZ | EA | EB | EC | ED | EE | EF | EG | EH | EI | EJ | EK | EL | EM | EN | EO | EP | EQ | ER | ES | ET | EU | EV | EW | EX | EY | EZ | FA | FB | FC | FD | FE | FF | FG | FH | FI | FJ | FK | FL | FM | FN | FO | FP | FQ | FR | FS | FT | FU | FV | FW | FX | FY | FZ | GA | GB | GC | GD | GE | GF | GG | GH | GI | GJ | GK | GL | GM | GN | GO | GP | GQ | GR | GS | GT | GU | GV | GW | GX | GY | GZ | HA | HB | HC | HD | HE | HF | HG | HH | HI | HJ | HK | HL | HM | HN | HO | HP | HQ | HR | HS | HT | HU | HV | HW | HX | HY | HZ | IA | IB | IC | ID | IE | IF | IG | IH | II | IJ | IK | IL | IM | IN | IO | IP | IQ | IR | IS | IT | IU | IV | IW | IX | IY | IZ | JA | JB | JC | JD | JE | JF | JG | JH | JI | JJ | JK | JL | JM | JN | JO | JP | JQ | JR | JS | JT | JU | JV | JW | JX | JY | JZ | KA | KB | KC | KD | KE | KF | KG | KH | KI | KJ | KK | KL | KM | KN | KO | KP | KQ | KR | KS | KT | KU | KV | KW | KX | KY | KZ | LA | LB | LC | LD | LE | LF | LG | LH | LI | LJ | LK | LL | LM | LN | LO | LP | LQ | LR | LS | LT | LU | LV | LW | LX | LY | LZ | MA | MB | MC | MD | ME | MF | MG | MH | MI | MJ | MK | ML | MM | MN | MO | MP | MQ | MR | MS | MT | MU | MV | MW | MX | MY | MZ | NA | NB | NC | ND | NE | NF | NG | NH | NI | NJ | NK | NL | NM | NN | NO | NP | NQ | NR | NS | NT | NU | NV | NW | NX | NY | NZ | OA | OB | OC | OD | OE | OF | OG | OH | OI | OJ | OK | OL | OM | ON | OO | OP | OQ | OR | OS | OT | OU | OV | OW | OX | OY | OZ | PA | PB | PC | PD | PE | PF | PG | PH | PI | PJ | PK | PL | PM | PN | PO | PP | PQ | PR | PS | PT | PU | PV | PW | PX | PY | PZ | QA | QB | QC | QD | QE | QF | QG | QH | QI | QJ | QK | QL | QM | QN | QO | QP | QQ | QR | QS | QT | QU | QV | QW | QX | QY | QZ | RA | RB | RC | RD | RE | RF | RG | RH | RI | RJ | RK | RL | RM | RN | RO | RP | RQ | RR | RS | RT | RU | RV | RW | RX | RY | RZ | SA | SB | SC | SD | SE | SF | SG | SH | SI | SJ | SK | SL | SM | SN | SO | SP | SQ | SR | SS | ST | SU | SV | SW | SX | SY | SZ | TA | TB | TC | TD | TE | TF | TG | TH | TI | TJ | TK | TL | TM | TN | TO | TP | TQ | TR | TS | TT | TU | TV | TW | TX | TY | TZ | UA | UB | UC | UD | UE | UF | UG | UH | UI | UJ | UK | UL | UM | UN | UO | UP | UQ | UR | US | UT | UU | UV | UW | UX | UY | UZ | VA | VB | VC | VD | VE | VF | VG | VH | VI | VJ | VK | VL | VM | VN | VO | VP | VQ | VR | VS | VT | VU | VV | VW | VX | VY | VZ | WA | WB | WC | WD | WE | WF | WG | WH | WI | WJ | WK | WL | WM | WN | WO | WP | WQ | WR | WS | WT | WU | WV | WW | WX | WY | WZ | XA | XB | XC | XD | XE | XF | XG | XH | XI | XJ | XK | XL | XM | XN | XO | XP | XQ | XR | XS | XT | XU | XV | XW | XX | XY | XZ | YA | YB | YC | YD | YE | YF | YG | YH | YI | YJ | YK | YL | YM | YN | YO | YP | YQ | YR | YS | YT | YU | YV | YW | YX | YY | YZ

If I change the &quot;Z&quot; to a &quot;Y&quot;, I get the following result :

A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y |

Is there a bug with the <= &quot;Z&quot; vs <= &quot;Y&quot;? Why is &quot;Y&quot; working and not &quot;Z&quot;?

Moonlight

Rich
04-28-2001, 10:09 PM
Perhaps this will explain the mystery:

for ($char = 'A'; $char <= 'Z'; $char++) {
[nbsp][nbsp][nbsp][nbsp] echo ord($char) . &quot; | &quot;;
}

produces:

65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 65 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 66 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 67 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 68 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 69 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 70 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 71 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 72 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 73 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 74 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 75 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 76 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 77 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 78 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 79 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 80 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 81 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 82 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 83 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 84 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 85 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 86 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 87 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 88 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 | 89 |

I'll leave as an exercise (and research) how to correct the actual coding problem. :)

(But feel free to post back here if you are still stuck *after* doing the homework assignment) :)

Rich
[This message has been edited by Rich (edited 04-28-01@9:14 pm)]

Moonlight
04-28-2001, 11:34 PM
I solved the problem by doing :


for ($char = ord('A'); $char <= ord('Z'); $char++) {
[nbsp][nbsp][nbsp][nbsp] echo chr($char) . &quot; | &quot;;
}


I figured out what you meant. Why using it using the Unicode or 'ASCII' when doing the ++ after &quot;Z&quot;?

Most programmation language if you do ++ on a char Z, it does not return 'AA'.

Sometime the logic method isn't the best method to do it, I guess.

Thanks Rich.

Moonlight

Rich
04-29-2001, 01:03 AM
Why using it using the Unicode or 'ASCII' when doing the ++ after &quot;Z&quot;? This is one of the trickier parts of using &quot;letters&quot; as numbers. The original ascii tables were designed so that the numeric codes for A-Z are together to make comparisons easier. However, this is not the case for sorted letter sequences &quot;greater than&quot; Z (like AA, AB, etc.).

Since we expect B + 1 = C it must naturally follow that Z + 1 = AA. At least, this is how many languages handle these cases.

However, when doing &quot;letter math&quot; you must make sure you do not go beyond this range as comparisons then breakdown. Remember, AA is not a character (it's actually two), so there is no representation for this in the ascii table (or unicode table). Therefore, there is no such thing as an ord('AA') specifically. In this case, PHP returns the ord of the first character in the string, which is probably better than generating an error. :)

Internally if you say if 'A' < 'B', PHP interprets this as if ord('A') < ord('B'). Also note that 'for' loops do their comparisons at the start of the loop. When 'Z' + 1 is evaluated it becomes 'AA' which results in an ord('A') so the loop keeps running because this is still less than ord('Z').

The corrected code version works because you are comparing ord('Z') to ord('Z')+1, which is guaranteed to stop the loop.

Rich

Justin
04-29-2001, 02:37 AM
Hm, I was going to try and post a nice one-line solution, but PHP doesn't handle FOR loops quite like other languages.

In C, this works:
</font><font face="Courier" size="3">
#include <stdio.h>
#include <string.h>

void main (void) {
[nbsp][nbsp] char c;
[nbsp][nbsp] for(c='@';c!='Z';fprintf(stdout,&quot;%c | &quot;, ++c));

}
</font><font face="Verdana, Arial" size="2">
But in PHP, the following results in a parse error:
</font><font face="Courier" size="3">
for($c='@';$c!='Z';echo ++$c.' | ');
</font><font face="Verdana, Arial" size="2">
Ordinarily, the FOR loop takes three arguments:

- The initializer; this is code that is run at the start of the loop.
- The condition; the loop is executed as long as the condition is true.
- The incrementer, but this is normally not limited to incrementing. In fact, in C you can put any valid code (or block of code) in there, as the above example demonstrates. But in PHP, apparenlty you can't...

Though this is completely irrelevant... I just like one-line solutions, which are sometimes hard to come by in PHP...

------------------
Justin Nelson
SFE Software (http://www.sfesoftware.com)

Rich
04-29-2001, 03:06 AM
I just like one-line solutions, which are sometimes hard to come by in PHP... print join &quot; | &quot;, ('A'..'Z'); :P

Rich
-- !PHP

Terra
04-29-2001, 03:14 AM
God bless the perls of wisdom...[nbsp][nbsp]:)

--
Terra
--('A'..'Z')--
FutureQuest

sheila
04-29-2001, 03:21 AM
[nbsp][nbsp] for(c='@';c!='Z';fprintf(stdout,&quot;%c | &quot;, ++c));

(1) why the at-symbol? Is that some sort of typo? Did you mean capital 'a' ?
(2) won't this give you a trailing pipe character after the capital 'z' ?

<added>
OH! going back and re-reading the original post, I see that they wanted a trailing pipe after the 'Z'.


[This message has been edited by sheila (edited 04-29-01@02:24 am)]

Justin
04-29-2001, 08:37 AM
The '@' is not a typo; rather, it is the character just before capital A, and since I'm incrementing the variable *before* printing it, 'A' will be the first character printed.

An easier way would have been to start with 'A' and use >='Z', since C won't have the Unicode problem, but I was trying to come up with something that could be plugged into PHP (actually I was trying to see why that method wouldn't work in PHP).

Rich -- you got me on that one, that was pretty slick. It's very late (early now?), and I've been staring at the deep blue C all day (C code in mcedit)...

------------------
Justin Nelson
SFE Software (http://www.sfesoftware.com)

sheila
04-29-2001, 11:19 AM
The '@' is not a typo; rather, it is the character just before capital A, and since I'm incrementing the variable *before* printing it, 'A' will be the first character printed. Doh! I did notice that you were using the pre-increment operator. And I looked at the loop ending condition, carefully, to see why you stopped before getting to Z. I just didn't look/think carefully about the beginning!