2016-06-24 13 views
0

Ich habe ein Problem durch die Anzahl der Zeichen in der Zeichenfolge zu definieren. Zum Beispiel habe ich den folgenden Code:Zählen der Anzahl der Zeichen in einer Zeichenfolge

IDENTIFICATION DIVISION. 
PROGRAM-ID. TASK1. 
DATA DIVISION. 
FILE SECTION. 
WORKING-STORAGE SECTION. 
01 SOURCE-STRING PIC X(50) VALUE " The length of string ". 
01 LATTER-COUNTER PIC 99. 
PROCEDURE DIVISION. 
MAIN-PROCEDURE. 
    MOVE 0 TO LATTER-COUNTER 
    INSPECT SOURCE-STRING TALLYING LATTER-COUNTER FOR [???] 
STOP RUN. 

Was muss ich die Länge von SOURCE-STRING finden schreiben (Zeichenfolge, die in Wert „Die Länge der Zeichenkette“ geschrieben wird). Die Länge muss aus 26 Zeichen bestehen (einschließlich führende Leerzeichen = 2 und letzte Leerzeichen = 4).

+1

COBOL hat keine "Strings". Sie haben 28 nachgestellte Leerzeichen in diesem Feld und alle 28 sind identisch. Sie müssen klären, was Sie tun müssen und warum. Verwenden Sie den Bearbeitungslink unter Ihrer Frage, um Informationen hinzuzufügen. Und 'MOVE' ist ein reserviertes Wort, man kann es nicht einfach in die Mitte eines' INSPECT' stecken und erwarten, dass etwas Nützliches passiert. –

+0

die 'MOVE' war eindeutig ein Fehler, ich habe den Code korrigiert –

+0

@ sky_diver89 Funktioniert eine der bereitgestellten Antworten für Sie? Wenn ja: bitte als Antwort markieren, wenn nein: Bitte kommentieren Sie die Antwort, die Sie vermissen [oder bearbeiten Sie Ihre Frage, wenn die Kommentare aufgrund der Reputation nicht funktionieren]. –

Antwort

3

Wie Bill sagte:

COBOL nicht "Strings" hat. Sie haben 28 nachgestellte Leerzeichen in diesem Feld und alle 28 sind identisch.

Wenn Sie die Länge, einschließlich der Anzahl der verwendeten Leerzeichen am Ende wissen, aber nicht die hinteren Räume in dem Feld dann nicht MOVE etwas in (oder VALUE dafür verwenden), aber das Feld (zum Beispiel initialisieren mit MOVE ALL 'x00' TO FIELD) und verwenden Sie STRING, um die Daten zu erhalten (auf diese Weise hätten Sie sogar einen "C" -String). Dies ermöglicht es Ihnen, eine INSPECT ... BEFORE FIRST x'00' zu tun.

Andere Optionen prüfen:

  • FUNCTION LENGTH (content)
  • STRING content INTO ... WITH POINTER LATTER-COUNTER (muss mit 1 beginnen)

Wir können eine bessere Antwort geben, wenn Sie mehr Informationen (über edit) zu Ihrer Frage hinzufügen (einschließlich des von Ihnen verwendeten COBOL-Compilers).

+0

Um die abschließende binäre Null zuverlässig zu erhalten, muss das Feld ein Byte länger sein. FUNCTION LENGTH ('literal') könnte die Antwort sein :-) –

+0

Obwohl kompliziert durch das tatsächliche Beispiel hier, nur bekommen eine gezählte Länge, die nachfolgende Leerzeichen abwertet (alle von ihnen, daher die Komplikation relativ zum Literalwert hier gezeigt), ist 'FUNCTION STORED-CHAR-LENGTH (Feld)'. Das ist also keine Antwort, nur ein Kommentar/Hinweis für alle mit ähnlichen, aber weniger strengen Anforderungen. –

0

Sie könnten NULL verwenden, um das Ende der Zeichenfolge anzugeben.

Zuerst initialisieren SOURCE-STRING-NULL:

01 SOURCE-STRING PIC X(50) VALUE NULL. 

dann statt MOVE der Verwendung der Zeichenfolge auf Ihre Variable zu bewegen, verwenden Sie die STRING Anweisung:

STRING " The length of string " INTO SOURCE-STRING 

Die ersten 26 Zeichen bewegt werden in SOURCE-STRING, aber die verbleibenden Zeichen bleiben unverletzt, NULL Bytes am Ende der Zeichenfolge verlassen. Dann können Sie bestimmen, wo die NULL Bytes beginnen.

Alternativ Sie STRING mit einem POINTER verwenden können, um automatisch die Zeichen zu zählen bewegt:

WORKING-STORAGE SECTION. 

01 SOURCE-STRING PIC X(50) VALUE NULL. 
01 STR-PTR PIC 9(3). 

PROCEDURE DIVISION. 

    MOVE 1 TO STR-PTR 
    STRING " The length of string " 
    INTO SOURCE-STRING 
    POINTER STR-PTR 
    SUBTRACT 1 FROM STR-PTR 

STR-PTR die Länge der aktuellen Zeichenfolge enthält. Beachten Sie, dass STR-PTR explizit auf 1 festgelegt werden muss, bevor Sie den Befehl STRING verwenden.

+0

'VALUE NULL' (ich nehme an, Sie haben getestet) muss eine AcuCOBOL Extension sein. AcuCOBOL hat viele :-). VALUE LOW-VALUES ist der transportable Weg, dies zu tun (unter der Annahme, dass niemand die Sortierfolge neu anordnet). Warum MOVE 1 zu STR-PTR und dann SUBTRACT 1 von ihm später? Warum nicht ZERO BEWEGEN ... und den SUBTRACT ablegen? "Z-Literale" kann verwendet werden, wenn es immer ein Literal ist (fügt eine binäre Null an das Literal an), aber Sie müssen dann immer sicherstellen, dass das Feld ein Byte länger ist als sonst notwendig. –

+0

Mit ACUCOBOL-GT, wenn wir 'ZERO' als Wert für den' POINTER' verwenden, wird es irgendwie nicht funktionieren, siehe [allgemeine Regel # 4] (https://supportline.microfocus.com/documentation/acucorpproducts/docs/ v6_online_doc/gtman3/gt36138.htm) in der Dokumentation. Ich kenne die Details anderer Laufzeiten nicht, aber ich habe nur Zugang zu ACUCOBOL. In der Tat wird "LOW-VALUES" den Wert wahrscheinlich auf ein NULL-Byte setzen. Man kann auch 'X'0'' benutzen, glaube ich. –

+0

Sie haben den POINTER korrekt. Es ist die nächste verfügbare Position für Daten, muss also größer als Null und kleiner als die Länge des Feldes sein. Nicht alle Betriebssysteme haben einen "NULL" -Wert. Nach Standard hat COBOL nur NULL für Dinge, die Adressen sein können. Bei einem Hex-Literal müssen Sie ALLES verwenden, um das Leerzeichen zu erhalten. Um die Länge eines Literals zu erhalten, wäre FUNCTION LENGTH am besten, wenn dies wirklich die Aufgabe ist, es würde zur Kompilierzeit ausgewertet werden. –

Verwandte Themen