| |
| Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
Autor
|
Thema: string umformen (1582 mal gelesen)
|
cadplayer Ehrenmitglied CADniker
Beiträge: 1832 Registriert: 28.04.2009
|
erstellt am: 22. Jan. 2014 16:24 <-- editieren / zitieren --> Unities abgeben:
Kann mir jemand einen Tip geben, wie ich diesen string "\\A1;NB +7.01\\PVG +4.41" in selbigen, bloss mit anderen Zahlenwerten übergebe (erhöht um +1) "\\A1;NB +8.01\\PVG +5.41" ------------------ Gruss Dirk http://cadplayerlounge.blogspot.se Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadffm Moderator 良い精神
Beiträge: 21533 Registriert: 03.06.2002 Alles
|
erstellt am: 22. Jan. 2014 16:35 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
EIN Beispiel reicht da wohl kaum um nicht raten zu müssen. Generell gilt: String Handling Funktionen kennst du ja, ist in der Hilfe und jedem Buch und Tutorial beschrieben, in letzteren sind sogar schon fertig sub-Routinen die noch mehr Arbeit erleichtern. Grundsätzlich mußt du den String auseinander nehmen und neu zusammen setzen. WIE man das im jeweiligen Fall machen muß/kann ist die Arbeit die es zu machen gilt, Code eintippen ist nur Beiwerk. Dafür muß man aber alle Informationen zu den möglichen Quell-Strings kennen. Wenn ich nur diesen einen sehe, würde ich mich spontan an die PUNKTe halten, alles direkt vor einem Punkt was zusammen einen Integer ergibt, wird um 1 erhöht. Aber morgen kommt einer mit einem String um die Ecke bei dem ein Punkt auch noch an anderer Stelle verwendet wird, ebenfalls mit einer "Zahl" vorneweg, die soll aber natprlich nicht erhöht werden usw. ------------------ CAD on demand GmbH - Beratung und Programmierung rund um AutoCAD [Diese Nachricht wurde von cadffm am 22. Jan. 2014 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadplayer Ehrenmitglied CADniker
Beiträge: 1832 Registriert: 28.04.2009
|
erstellt am: 22. Jan. 2014 16:58 <-- editieren / zitieren --> Unities abgeben:
|
Brischke Moderator CAD on demand GmbH
Beiträge: 4171 Registriert: 17.05.2001 AutoCAD 20XX, defun-tools (d-tools.eu)
|
erstellt am: 22. Jan. 2014 17:10 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
|
cadffm Moderator 良い精神
Beiträge: 21533 Registriert: 03.06.2002 Alles
|
erstellt am: 22. Jan. 2014 17:18 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
Wenn man davon ausgeht das die Zahlen immer Vorzeichen, Plus ODER MINUS haben und diese Zeichen sonst nicht verwendet werden - klar. Wenn man der Fragesteller wäre, dann hätte man es unter Umständen extrem einfach und würde immer das 4.Zeichen einer Zeile als Vorzechen herauslesen (ich nehme an, aus -3.05 wird -2.05 ?) und den REAl ab Stelle 5. Aber so ist es eben, derjenige der die gesamte Aufgabenstellung kennt ist im Vorteil. ------------------ CAD on demand GmbH - Beratung und Programmierung rund um AutoCAD Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
Beiträge: 1734 Registriert: 11.10.2004 Window 10 ACAD 2021 CIVIL 2021 BricsCAD V14-V22 Intel(R) Core(TM)i5-8250U CPU @ 1.60GHz 1.80 GHz 16.0GB RAM NVIDIA GeForce GTX 1050<P>
|
erstellt am: 22. Jan. 2014 18:45 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
Hallo, ich habe mich mal kurz probiert, Vorzeichen werden aber nicht berücksichtigt, kann man bei Bedarf ja noch einbauen. Im Grunde genommen habe ich mit der Funktion den String in einen Zahlencode umgewandelt und kann dann über MEMBER bestimmen, ob Zahl (und Dezimalpunkt) oder sonst ein Zeichen. Wenn die Folge der Zahlen z.B. eine Länge von größergleich 3 hat, dann ist das eine Zahl, wo der Additionswert angebracht wird, viel Spaß damit: Code:
(defun c:test ( / ADDWERT ART LISTE LISTE1 N STRING TEMP ) (setq addWert 1.0) (setq string(vl-string->list "\\A1;NB +7.01\\PVG +4.41") liste (vl-string->list "12345657890.") art (not(member (car string)liste)) temp (list (list art (car string))) string (cdr string) ) (while string (if (= art (not(member(car string)liste))) (setq temp (cons (list art (car string))temp)) (setq art (not(member(car string)liste)) liste1 (cons (reverse temp)liste1) temp (list (list art (car string))))) (setq string (cdr string))) (setq liste1 (reverse(cons (reverse temp)liste1))) (apply'strcat (mapcar '(lambda(A) (if (car(car A)) (vl-list->string(mapcar 'cadr A)) (if (and(>=(length A)3) (member (car(vl-string->list "."))(mapcar 'cadr A))) (rtos(+ addWert (atof(vl-list->string(mapcar 'cadr A))))2 2) (vl-list->string(mapcar 'cadr A)))))liste1)) )
------------------ viele Grüße Jörn http://www.bosse-engineering.com Rahmen einfügen Youtube Stammtisch Wolfsburg Februar 2014 Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
cadffm Moderator 良い精神
Beiträge: 21533 Registriert: 03.06.2002 Alles
|
erstellt am: 22. Jan. 2014 23:05 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
|
cadplayer Ehrenmitglied CADniker
Beiträge: 1832 Registriert: 28.04.2009
|
erstellt am: 23. Jan. 2014 15:55 <-- editieren / zitieren --> Unities abgeben:
Einfach genial Jörn! Passt sehr gut in meinen Code hinein! Ich muss natürlich gleich hinten anstellen, wie machst du das bloss Der Mechanismus ist mir noch nicht hundert prozentig klar: erster Teil klar: du schmeisst das (vl-list->string '(92)) (\\) weg! zweiter Teil ungefähr klar (mangels meiner Umsetzungskenntnisse) in string steht bspw: '(80 68 49 54 48 32 86 71 32 43 53 46 ... ) in liste1 steht bspw: '(((nil 52) (nil 46) (nil 52) (nil 51)) ((T 32) (T 86) (T 71) (T 32) (T 43)) ((nil 49) (nil 54) (nil 48)) ((T 59) (T 83) (T 69) (T 82) (T 86) (T 73) (T 83) (T 92) (T 80) (T 83)) ((nil 49)) ((T 92) (T 65))) Mir ist hier klar das ein (nil zahl) eine Ziffer ergibt Im letzten Teil und das ist das heftigste Schmankel schaffst du es problemlos die Textzeile mit den manipulierten REALs zusammenzusetzen. (vl-list->string(mapcar 'cadr A)) ->"\\A" ; das erste stringelement Jetzt war ich der Auffassung, in liste1 stehen nur Listen der Silben ob type REAL oder STR Aber hier kommen gleich STR-silben (vl-list->string(mapcar 'cadr A)) -> ";SERVIS\\PS" Und dann wird es gleich ganz unverständlich, dass scheinbar hier der neue Wert zu addiert oder abgezogen wird (rtos(+ addWert (atof(vl-list->string(mapcar 'cadr A))))2 2) Wie gesagt, echt toll! Wahnsinns Umsetzung! Und für mich super Lernstoff! Vielen Dank! ------------------ Gruss Dirk http://cadplayerlounge.blogspot.se Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
Beiträge: 1734 Registriert: 11.10.2004 Window 10 ACAD 2021 CIVIL 2021 BricsCAD V14-V22 Intel(R) Core(TM)i5-8250U CPU @ 1.60GHz 1.80 GHz 16.0GB RAM NVIDIA GeForce GTX 1050<P>
|
erstellt am: 23. Jan. 2014 16:40 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
Hallo Dirk, wo fange ich an, wo hör ich auf, ich denke, Du mußt den Code selber einmal in Einzelschritten durchbuggen und die Variablen-Inhalte dabei beobachten. Ich habe versucht, den Code mit Kommentaren zu versehen, ist gar nicht so einfach, so etwas mit Worten zu beschreiben:
Code:
(defun c:test ( / ADDWERT ART LISTE LISTE1 N STRING TEMP ) (setq addWert 1.0) ;;;1. den ganzen String in Zahlencodes umwandeln (setq string(vl-string->list "\\A1;NB +7.01\\PVG +4.41")) ;;;2. die Zahlencodes für die Ziffern und den Dezimalpunkt bestimmen (setq liste (vl-string->list "12345657890.")) ;;;3. Inaitialisierung Variable "art", wenn erste Zeichen eine Zahl oder ein Dezimalpunkt, ;;; dann nil, sonst T (setq art (not(member (car string)liste))) ;;;4. temporäre Variable, die solange gleich"art"ige Zeichen sammelt, bis die "art" wechselt (setq temp (list (list art (car string)))) ;;;5. weil das erste Zeichen bereits in temp enthalten ist muss es aus der Variablen "string" ;;;entfernt werden (setq string (cdr string)) ;;;6. In der While-Schleife wird immer das erste Element ausgewertet ;;;in die Varialbe temp wird immer dem ersten Element die "art" für die spätere ;;;Erkennung vorangestellt. (while string (if (= art (not(member(car string)liste))) ;;;6a. Wenn die Art unverändert ist wird das erste Element zu "temp" gecons't (setq temp (cons (list art (car string))temp)) ;;;6b. Wenn die Art wechselt wird "temp" reverse'd zu "liste1" gecons't und ;;; "temp" wird mit einem Eintrag neu belegt (setq art (not(member(car string)liste)) liste1 (cons (reverse temp)liste1) temp (list (list art (car string))))) ;;;6c. Erstes Element entfernen (setq string (cdr string))) ;;;7. Nach der While-Schleife den Inhalt von "temp" zu "liste1", diese dann ;;;auch reversen, damit die Reihenfolge des ursprünglichen Strings wiederhergestellt ist (setq liste1 (reverse(cons (reverse temp)liste1))) ;;;9. mit (apply 'strcat werden alle Elemente einer Liste zu einem String zusammengefasst ;;;In diesem Fall alle RÜCKGABE'n der folgenden MAPCAR-Schleife (apply'strcat ;;;8. In der Mapcar-Schleife werden die einzelnen Elemente von Liste1 als ;;;Variable "A" ausgewertet (mapcar '(lambda(A) ;;;8a. WENN das erste Element des ersten Elementes von A = 'T (if (car(car A)) ;;;(mapcar 'cadr A) => Liste mit den Zahlencodes, die "art" ist dann ;;;nicht mehr enthalten ;;;RÜCKGABE: Liste mit Zahlencodes wieder in String umgewandelt (vl-list->string(mapcar 'cadr A)) ;;;8b. (muss automatisch Zahl oder Dezimalpunkt sein, weil Prüfung 8a. negativ) ;;;WENN die Länge der Liste größergleich 3 UND der Zahlencode ;;; eines Dezimalpunktes ;;;in der ZahlencodeListe von "A" enthalten ;;;(dann gehe ich davon aus eine gültige Zahl erwischt zu haben) (if (and(>=(length A)3) (member (car(vl-string->list "."))(mapcar 'cadr A))) ;;;8c. DANN nimm die Zahlencodes von "A", wandel sie wieder in String, ;;;mache mit ATOF eine REAL-Zahl, addieren den "addWert" und mache ;;;einen String mit 2 Nachkommastellen: RÜCKGABE (rtos(+ addWert (atof(vl-list->string(mapcar 'cadr A))))2 2) ;;;;WENN Prüfung 8b. negativ, dann mache als Zahlencodes von "A" ;;;einen String => RÜCKGABE (vl-list->string(mapcar 'cadr A))))) liste1))
)
------------------ viele Grüße Jörn http://www.bosse-engineering.com Rahmen einfügen Youtube Stammtisch Wolfsburg Februar 2014 Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
joern bosse Ehrenmitglied Dipl.-Ing. Vermessung
Beiträge: 1734 Registriert: 11.10.2004 Window 10 ACAD 2021 CIVIL 2021 BricsCAD V14-V22 Intel(R) Core(TM)i5-8250U CPU @ 1.60GHz 1.80 GHz 16.0GB RAM NVIDIA GeForce GTX 1050<P>
|
erstellt am: 23. Jan. 2014 16:42 <-- editieren / zitieren --> Unities abgeben: Nur für cadplayer
Zitat: Original erstellt von joern bosse: Hallo Dirk, wo fange ich an, wo hör ich auf, ich denke, Du mußt den Code selber einmal in Einzelschritten durchbuggen und die Variablen-Inhalte dabei beobachten.Ich habe versucht, den Code mit Kommentaren zu versehen, ist gar nicht so einfach, so etwas mit Worten zu beschreiben: (die in die nächste Zeile gerückten Kommentare mußt Du Dir im Editor richtig hinschieben)
Code:
(defun c:test ( / ADDWERT ART LISTE LISTE1 N STRING TEMP ) (setq addWert 1.0) ;;;1. den ganzen String in Zahlencodes umwandeln (setq string(vl-string->list "\\A1;NB +7.01\\PVG +4.41")) ;;;2. die Zahlencodes für die Ziffern und den Dezimalpunkt bestimmen (setq liste (vl-string->list "12345657890.")) ;;;3. Inaitialisierung Variable "art", wenn erste Zeichen eine Zahl oder ein Dezimalpunkt, ;;; dann nil, sonst T (setq art (not(member (car string)liste))) ;;;4. temporäre Variable, die solange gleich"art"ige Zeichen sammelt, bis die "art" wechselt (setq temp (list (list art (car string)))) ;;;5. weil das erste Zeichen bereits in temp enthalten ist muss es aus der Variablen "string" ;;;entfernt werden (setq string (cdr string)) ;;;6. In der While-Schleife wird immer das erste Element ausgewertet ;;;in die Varialbe temp wird immer dem ersten Element die "art" für die spätere ;;;Erkennung vorangestellt. (while string (if (= art (not(member(car string)liste))) ;;;6a. Wenn die Art unverändert ist wird das erste Element zu "temp" gecons't (setq temp (cons (list art (car string))temp)) ;;;6b. Wenn die Art wechselt wird "temp" reverse'd zu "liste1" gecons't und ;;; "temp" wird mit einem Eintrag neu belegt (setq art (not(member(car string)liste)) liste1 (cons (reverse temp)liste1) temp (list (list art (car string))))) ;;;6c. Erstes Element entfernen (setq string (cdr string))) ;;;7. Nach der While-Schleife den Inhalt von "temp" zu "liste1", diese dann ;;;auch reversen, damit die Reihenfolge des ursprünglichen Strings wiederhergestellt ist (setq liste1 (reverse(cons (reverse temp)liste1))) ;;;9. mit (apply 'strcat werden alle Elemente einer Liste zu einem String zusammengefasst ;;;In diesem Fall alle RÜCKGABE'n der folgenden MAPCAR-Schleife (apply'strcat ;;;8. In der Mapcar-Schleife werden die einzelnen Elemente von Liste1 als ;;;Variable "A" ausgewertet (mapcar '(lambda(A) ;;;8a. WENN das erste Element des ersten Elementes von A = 'T (if (car(car A)) ;;;(mapcar 'cadr A) => Liste mit den Zahlencodes, die "art" ist dann ;;;nicht mehr enthalten ;;;RÜCKGABE: Liste mit Zahlencodes wieder in String umgewandelt (vl-list->string(mapcar 'cadr A)) ;;;8b. (muss automatisch Zahl oder Dezimalpunkt sein, weil Prüfung 8a. negativ) ;;;WENN die Länge der Liste größergleich 3 UND der Zahlencode ;;; eines Dezimalpunktes ;;;in der ZahlencodeListe von "A" enthalten ;;;(dann gehe ich davon aus eine gültige Zahl erwischt zu haben) (if (and(>=(length A)3) (member (car(vl-string->list "."))(mapcar 'cadr A))) ;;;8c. DANN nimm die Zahlencodes von "A", wandel sie wieder in String, ;;;mache mit ATOF eine REAL-Zahl, addieren den "addWert" und mache ;;;einen String mit 2 Nachkommastellen: RÜCKGABE (rtos(+ addWert (atof(vl-list->string(mapcar 'cadr A))))2 2) ;;;;WENN Prüfung 8b. negativ, dann mache als Zahlencodes von "A" ;;;einen String => RÜCKGABE (vl-list->string(mapcar 'cadr A))))) liste1))
)
------------------ viele Grüße Jörn http://www.bosse-engineering.com Rahmen einfügen Youtube Stammtisch Wolfsburg Februar 2014 Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |