apop85
Goto Top

Copy NUL hängt sich auf. Warum?

Halle liebe leute von administrator.de. Lange war ich nicht mehr aktiv hier aber es hat mch mal wieder gepackt face-smile

Ich wollte mir mal ein kleines klassisches Textadventure zusammenbasteln. In selbigen habe ich eine Datei namens "inv.inv" angelegt welche das Inventar das Spiels darstellen wird. In diesem Inventar befindet sich z.b. folgende Auflistung:
food.Apfel.5
food.Apfel.5
food.Fleisch.10
...
Nun möchte ich, dass im Inventar z.b. ein Apfel gegessen werden kann. Da dieses Objekt doppelt vorhanden ist, möchte ich, dass nur ein Eintrag aus inv.inv gelöscht wird und der andere bestehen bleibt:
food.Apfel.5
food.Fleisch.10
...
Ich habe es mit einer For-Schlafe versucht welche nach die ganze Datei nach Apfel durchsucht und sobald sie einen gefunden hat einen Counter auf 1 stellt und damit den 2. Apfel nicht auch entfernt wird.
Leider ist das letzte mal, dass ich was grössere mit BATCH gemacht habe schon über 2 Jahre her... Eigentlich habe ich das schon mal hingekriegt aber ich glaube ich bräuchte da nochmals einen Schubs in die richtige Richtung ;)

Mein Ansatz:
if exist %tmp%\ARK.tmp del %tmp%\ARK.tmp /q/f >NUL
if not exist %tmp%\ARK.tmp copy NUL %tmp%\ARK.tmp >NUL
for /f "tokens=1-3 delims=." %%i in ('^< "%appdata%\ARKsta\inv.inv" findstr /n "^"') do set "type=%%j"& set "name=%%k"& set "plushp=%%l"& set /a cnt+=1  
for /l %%i in (1,1,%cnt%) do (
setlocal enabledelayedexpansion

if %eingabe% NEQ !name%%! ( if "!type%%!" NEQ "" ( echo !type%%i!.!name%%i!.!plushp%%i! >>%tmp%\ARK.tmp ) )  
if %eingabe% == !name%%! ( if !counter%%! GEQ 1 ( echo !type%%i!.!name%%i!.!plushp%%i! >>%tmp%\ARK.tmp ) )
if %eingabe% == !name%%! ( if !counter%%! NEQ 1 set /a counter+=1 )

endlocal 
) 
goto :eof

Es soll einfach geprüft werden ob %eingabe% gleich dem gesuchten Namen ist, falls nicht, Daten übertragen nach %tmp%\ARK.tmp.
Ist %eingabe% gleich %name% soll der counter von 0 auf 1 gesetzt werden und jeder weitere Eintrag der ebenfalls Identisch ist mit %name% trozdem in %tmp%\ARK.tmp eingefügt werden.

Das Problem das ich habe liegt irgendwo hier:
if exist %tmp%\ARK.tmp del %tmp%\ARK.tmp /q/f >NUL
if not exist %tmp%\ARK.tmp copy NUL %tmp%\ARK.tmp >NUL

Sobald er den Copy-Befehl durchführt hängt sich das script auf.
Ich habe jedoch ähnliche Befehle bereits implementiert und diese Funktionieren auf die selbe Weise ohne Probleme

if not exist %appdata%\ARKsta mkdir %appdata%\ARKsta >NUL
if not exist %appdata%\ARKsta\save.sv copy NUL %appdata%\ARKsta\save.sv >NUL
if not exist %appdata%\ARKsta\inv.inv copy NUL %appdata%\ARKsta\inv.inv >NUL

Danke jetzt schon für eure Antworten face-smile Ihr seid die Besten

Grüsse Apop85

Content-Key: 272890

Url: https://administrator.de/contentid/272890

Printed on: April 19, 2024 at 20:04 o'clock

Member: rubberman
Solution rubberman May 25, 2015 updated at 16:17:44 (UTC)
Goto Top
Hallo Apop85

die Prüfung in der 2. Zeile ist ja eigentlich unnötig, da du bereits in der ersten Zeile die Datei löscht. Selbst das ist unnötig, da du die Datei gleich wieder erstellst. Warum COPY fehlschlägt, weiß ich zwar auf den ersten Blick auch nicht, aber ersetze doch die Zeilen 1 uns 2 mal mit einer einzigen
>%tmp%\ARK.tmp type NUL
Das ist lediglich eine andere Möglichkeit eine leere Datei zu erstellen.

Grüße
rubberman
Member: Apop85
Apop85 May 25, 2015 updated at 16:38:45 (UTC)
Goto Top
Danke für den Tipp.. Nur die For-Schleife funktioniert noch nicht ganz so wie ich will.

ich krieg zwar %name% und %plushp% richtig raus aber bei %type% habe ich immer noch ein "4:" vor der ausgabe (z.B. 4:food anstatt nur food). Ausserdem scheint der counter nicht zu funktionioeren. Er bleibt bei 0 hängen und die tmp Datei bleibt leer. Also auch wenn ich Apfel eingebe kommt das Fleisch nicht in die tmp.

:GETFOOD2
if exist %tmp%\ARK.tmp del %tmp%\ARK.tmp /q/f >NUL
>>%tmp%\ARK.tmp type NUL

for /f "tokens=1-3 delims=." %%i in ('^< "%appdata%\ARKsta\inv.inv" findstr /n "^"') do set "type=%%i"& set "name=%%j"& set "plushp=%%k"& set /a cnt+=1  
for /l %%i in (1,1,%cnt%) do (
setlocal enabledelayedexpansion

if %eingabe% NEQ !name%%! ( if "!type%%!" NEQ "" ( echo !type%%i!.!name%%i!.!plushp%%i! >>%tmp%\ARK.tmp ) )  
if %eingabe% == !name%%! ( if %counter% GEQ 1 ( echo !type%%!.!name%%!.!plushp%%! >>%tmp%\ARK.tmp ) )
if %eingabe% == !name%%! ( if %counter% NEQ 1 set /a counter=%counter%+1 ) 

endlocal 
) 
goto %memory%

Die For-Schleife soll einfach eine bestimmte Zeile in dem das Wort %eingabe% vor kommt löschen bzw. eine Zeile auslassen und dann die anderen Zeilen mit gleichem Inhalt ignorieren und mit in die TMP Datei schreiben.

Beispiel inv.inv - Datei:
food.Apfel.5
food.Fleisch.10
food.Fleisch.10

Beispiel ARK.tmp - Datei nach For-Schleife mit eingabe=Fleisch
food.Apfel.5
food.Fleisch.10

Grüsse Apop85


P.S.

mir würden auch die entsprechenden tags genügen die mich zu meiner Lösung führen ;D
Member: rubberman
Solution rubberman May 25, 2015 updated at 17:31:15 (UTC)
Goto Top
Da du findstr /n nutzt, wird eine Zeilennummer vor jede Zeile gesetzt. Offenbar hat deine Datei 4 Zeilen.
Definiere den Doppelpunkt als zusätzlichen Delimiter und werte die Tokens 2-4 aus.

Grüße
rubberman
Member: Apop85
Apop85 May 25, 2015 updated at 17:37:39 (UTC)
Goto Top
Hey rubberman

Danke für den Tip. Ausgabe %type% stimmt jetzt nur die ARK.tmp ausgabe geht noch nicht
Member: bastla
Solution bastla May 25, 2015 updated at 18:08:15 (UTC)
Goto Top
Hallo Apop85 und rubberman!

Mit etwas Verspätung (und nur oberflächlich getestet face-wink) noch ein Alternativvorschlag:
if exist %temp%\ARK.tmp del %temp%\ARK.tmp /q/f >NUL
set "schreiben="  
for /f "tokens=1-4 delims=:." %%i in ('findstr /n "^" "%appdata%\ARKsta\inv.inv"') do (  
    if "%eingabe%" NEQ "%%k" (  
        if "%%j" NEQ "" >>%temp%\ARK.tmp echo %%j.%%k.%%l  
    ) else (
        if defined schreiben (
           >>%temp%\ARK.tmp echo %%j.%%k.%%l
        ) else (
           set "schreiben=true"  
        )
    )
)
goto :eof
- erspart den Zähler und "delayedExpansion", indem einfach nur eine Schalter-Variable verwendet wird ...

Noch weiter vereinfacht (da ja Leerzeilen offensichtlich ohnehin nicht benötigt werden):
if exist %temp%\ARK.tmp del %temp%\ARK.tmp /q/f >NUL
set "schreiben="  
for /f "usebackq tokens=1-3 delims=." %%i in ("%appdata%\ARKsta\inv.inv") do (  
    if "%eingabe%" NEQ "%%j" (  
        >>%temp%\ARK.tmp echo %%i.%%j.%%k
    ) else (
        if defined schreiben (>>%temp%\ARK.tmp echo %%i.%%j.%%k) else (set "schreiben=true")  
    )
)
goto :eof
Grüße
bastla
Member: Apop85
Apop85 May 25, 2015 at 19:58:39 (UTC)
Goto Top
Danke bastla Funktioniert wie es soll.

Vielen vielen dank ;)