PDA

View Full Version : OFFSET zwischen POINTERs



Seiten : [1] 2

jsranko
20-02-15, 18:49
Hallo alle,

hat jemand eine Idee, wie man in COBOL Offset zwischen zwei POINTERs berechnen kann?



01 pointer1 POINTER.
01 pointer2 POINTER.
01 offset PIC S9(09) BINARY.

COMPUTE offset = pointer2 - pointer1.


Ich bin schon im Voraus dankbar.

LG J.

KingofKning
20-02-15, 20:02
Mal blöd gefragt, für was brauchst Du das?

GG

jsranko
20-02-15, 22:38
Es ist eine gute Frage.
API: strstr gibt mir eine Addresse zurück, wo sich gesuchte String befindet. Und diferenz zwischen Addressen, sagt mir genau die Position von gesuchter String.
Ich bin auf der nach einer Alternative von INSPECT, weil ich die langsam finde.

Fuerchau
21-02-15, 18:28
Der Inspect ist nun mal auch sehr mächtig.
Andererseits ist COBOL für Pointer gut geeignet.

77 MyPtr usage pointer.

LINKAGE SECTION.
01 MyVar.
05 F1 pic X(10).

PROCEDURE DIVISION.

SET ADRESS OF MyVar to Pointer.

Du kannst also das Ergebnis der strstr() eine Linkage-Variablen zuweisen.

Alternativ geht es natürlich auch per SQL, wobei hier die Variablendefinition als Begrenzer funktioniert (für C-Funktionen musst du ja ein X'00' ans Ende packen):

exec SQL set : MyPos = posstr('Suchfeld', : Source)
end-exec.

Wobei eben auch geschachtelte Funktionen sowie UDT's ganz praktisch sind.

jsranko
25-02-15, 09:52
Hi Fuerchau,

ich danke dir für deine Antwort, hat zwar mein Problem nicht gelöst aber hat mir eine Idee gezeigt, wie ich es lösen soll.

Ich habe es in CLLE gemacht, weil in CL mit Pointers besser arbeiten kann:



CALLPRC PRC('strstr') PARM((&strstr_st1 *BYVAL) +
(&strstr_st2 *BYVAL)) +
RTNVAL(&strstr_fnd)
IF COND(&strstr_fnd *EQ *NULL) THEN(DO)
CALLSUBR doENDPGM
ENDDO

CHGVAR &strstr_off (%OFS(&strstr_fnd)-%OFS(&strstr_st1))



Nochmals danke.

Rainer Ross
25-02-15, 11:28
Im neuen all-free RPG gehts auch. Es macht Sinn bei Variablen größer als 16MB, wo der %scan nicht mehr funktioniert. Beispielsweise bei Files aus dem IFS.


dcl-pr strstr pointer extproc(*dclcase);
##string pointer value options(*string);
##pattern pointer value options(*string);
end-pr;

dcl-s string varchar(60); // String
dcl-s pattern varchar(20); // Pattern
dcl-s result_p pointer; // Result-Pointer
dcl-s pos int(10); // Position

string = 'das ist ein toller text';
pattern = 'toll';

result_p = strstr(%addr(string:*data):%addr(pattern:*data));

if result_p <> *null; // Result-Pointer
pos = result_p - %addr(string:*data) + 1; // Position im String
endif;


Herzliche Grüße

Rainer

Fuerchau
25-02-15, 11:56
Variablen >16MB sind im *SNGLVL-Storage nicht möglich. Die Wahrscheinlichkeit dass 2 16MB-Bereiche direkt hintereinander liegen ist nicht gewährleistet.
Du kannst dein Speichermodel auf *TERASPACE umstellen, dann sind Variablen >16MB möglich und der %SCAN sollte eigentlich wieder funktionieren.

jsranko
25-02-15, 12:05
Hi Rainer,

ja genau RPG kann es, CL kann es aber COBOL :-( ... Schade.

Danke auch für deinen Tipp.

Rainer Ross
25-02-15, 13:38
Variablen >16MB sind im *SNGLVL-Storage nicht möglich. Die Wahrscheinlichkeit dass 2 16MB-Bereiche direkt hintereinander liegen ist nicht gewährleistet.
Du kannst dein Speichermodel auf *TERASPACE umstellen, dann sind Variablen >16MB möglich und der %SCAN sollte eigentlich wieder funktionieren.

danke für den Hinweis


ctl-opt dftactgrp(*no) alloc(*teraspace);

dschroeder
25-02-15, 16:30
ctl-opt dftactgrp(*no) alloc(*teraspace);

Nur mal so aus Interesse: Reicht es, alloc(*teraspace) einfach so deklarieren? Oder muss das Programm in einer bestimmten Activation Group ausgeführt werden? Bei uns läuft standardmäßig alles in ACTGRP(*CALLER).

Sind besondere Wandlungsoptionen auch noch erforderlich?

Dieter