36 Stimmen

PHP Zeicheniteration im For-Loop Problem

Mögliche Duplikate:
Warum gibt dieser Code nicht einfach die Buchstaben von A bis Z aus?

Warum kommt es, dass wenn ich die folgende Schleifenstruktur verwende, das richtige Ergebnis erhalte -

for ($c = "A"; $c <= "Y"; $c++)
{
    echo $c.", ";
}

Das Ergebnis, das ich erhalte ist -

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,

Was alles in Ordnung zu sein scheint. Aber wenn ich Y in der obigen Schleife durch Z ersetze, erhalte ich ungewöhnliche Ergebnisse

for ($c = "A"; $c <= "Z"; $c++)
{
    echo $c.", ";
}

Und das Ergebnis, das ich erhalte ist -

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, ...

Gibt es einen Grund für dieses Verhalten?

25voto

Rudi Visser Punkte 20718

Direkt aus dem PHP-Handbuch:

PHP folgt der Konvention von Perl bei der Verarbeitung von arithmetischen Operationen auf Zeichenvariablen und nicht von C. Zum Beispiel wird in PHP und Perl $a = 'Z'; $a++; zu $a 'AA', während in C a = 'Z'; a++; zu a '[' wird (ASCII-Wert von 'Z' ist 90, ASCII-Wert von '[' ist 91). Beachten Sie, dass Zeichenvariablen erhöht, aber nicht verringert werden können und selbst dann nur einfache ASCII-Zeichen (a-z und A-Z) unterstützt werden. Das Inkrementieren/Dekrementieren anderer Zeichenvariablen hat keine Auswirkung, der ursprüngliche String bleibt unverändert.

Der Grund, warum es weitergeht, liegt darin, dass Sie einen numerischen Vergleich versuchen (<= und AA < Z, ZA == Z (bei Verwendung von <=)), anstelle eines literalen Wertvergleichs (==).

In diesem Zusammenhang könnten Sie den folgenden Code verwenden:

for ($c = "A"; $c != "Z"; $c++)
{
    echo $c . ", ";
}

.. oder den tatsächlichen ordinalen Wert der Zeichen verwenden (was meiner Meinung nach die bessere Lösung ist):

for ($c = ord("A"); $c <= ord("Z"); $c++)
{
    echo chr($c) . ", ";
}

5voto

Mark Baker Punkte 204969

Verwenden Sie keine < oder > (oder >= oder <=) für Vergleiche beim Inkrementieren von Zeichen, verwenden Sie !==

for ($c = "A"; $c !== "AA"; $c++)
{
    echo $c.", ";
}

wo 'AA' "einer höher als" der Endpunkt ist, den Sie möchten

$lastCharacter = 'Z';
$lastCharacter++;
for ($c = "A"; $c !== $lastCharacter; $c++)
{
    echo $c.", ";
}

Alle Wörter, die aus ASCII-Zeichen bestehen (im Bereich A-Z), sind bis zu 'Z' <=, bis Sie zu ZA kommen, weil der Vergleich ein Zeichenkettenvergleich ist und "AA" < "Z" ist, wenn die Zeichen sortiert sind. Siehe meine Antwort auf eine frühere Version dieser Frage

1voto

Fabian Schmengler Punkte 23229

Glückwunsch, du hast eine der vielen Inkonsistenzen in PHP gefunden. Kurz gesagt: Die + und < Operatoren funktionieren bei Zeichenketten völlig unterschiedlich.

  • Das Erhöhen einer Einzelbuchstaben-Zeichenkette funktioniert wie erwartet
  • Das Erhöhen von Z ergibt AA und so weiter (denke an Excel-Spalten)
  • Das Vergleichen von Einzelbuchstaben-Zeichenketten funktioniert wie erwartet
  • Das Vergleichen von mehrbuchstabigen Zeichenketten erfolgt lexikographisch (Buchstabe für Buchstabe)

Jetzt kommt der interessante Randfall:

'Z' <= 'Z'    // weil gleich
'Z'++ == 'AA' // weil Magie
'AA' <= 'Z'   // weil A vor Z kommt

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X