Spacje w wierszu poleceń

0

Nie wiem, gdzie napisać, pytanie jest identyczne dla dwóch technologii, a konkretnie w C# i Java

Jak wiadomo, w programie uruchamianym z linii poleceń jest taka funkcja:

static void Main(string[] args)
{
}
public static void main(String[] args)
{
}

Jak widać, funkcja jest identyczna, czyli do funkcji wchodzi tablica napisów, a nie jeden napis. Można oczywiście zamienić to na jeden napis poprzez konkatenację wszystkich pozycji z umieszczeniem jednej spacji. Jednakże, jeżeli w wierszu poleceń są dwie spacje obok siebie, to będzie to zamienione na jedną spację. Czy ma to znaczenie, to już inny temat, chodzi mi o samą obsługę wiersza poleceń.

W jaki sposób można dostać argument wiersza polecenia tak, jak jest, bez żadnej obróbki (jaką jest np. zamiana na tablicę)? Teoretycznie, przy kilku spacjach w tablicy powinien być pusta pozycja, ale takiej nie ma, więc traci się informację o wielokrotnych spacjach.

Mam dowód na to, że to, co ja chcę, musi być możliwe: Miałem pewien program, którego źródła nie mam, ale wiem, że jest napisany w C++ z wykorzystaniem WinAPI, w Microsoft Visual Studio. W tym programie było możliwe wyświetlenie tego, co wchodzi jako parametr. jeżeli w parametrze były spacje obok siebie, to te spacje też wchodziły, czyli tak, jak było napisane, tak było w programie.

Jak uzyskać to samo w C# i w Java?

1

podanie kilku spaacji w cudzysłowie nie pomaga, program.exe param1 " " param3?

BTW w c# jest jeszcze Environment.CommandLine

5

Jakkolwiek to zrobisz, nie będzie to przenośne, bo na na Linuksie (na Windowsie nie wiem, podejrzewam że podobnie) za podzielenie linii poleceń na argumenty odpowiada powłoka, a nie system operacyjny. Wołanie systemowe exec przyjmuje już listę stringów i tyle… W związku z tym, hipotetyczne rozwiązanie w Javie wiązałoby się z jakimś brzydkim FFI, w C# pewnie podobnie…

Na ogół jest tak jak napisał @abrakadaber , jeśli chcesz mieć białe znaki w parametrze, bierzesz je w cudzysłów. Też pytanie po co w ogóle ci takie coś… Nie wyobrażam sobie rozsądnego zastosowania dla czegoś takiego…

0

podanie kilku spaacji w cudzysłowie nie pomaga, program.exe param1 " " param3?

Tak, można to zrobić i potem w analizie parametrów uwzględnić możliwość występowania cudzysłowu czy innego znaku w takim znaczeniu.

Można też w stylu OSX, czyli program.exe param1\ \ \ param3, a każdy znak inny niż litera, cyfra poprzedzony backslashem. Oczywiście w interpretacji polecenia trzeba to uwzględnić. Patrząc dalej, w tym stylu program.exe \p\a\r\a\m\1\ \ \ \p\a\r\a\m\3, po przetworzeniu będzie dokładnie to samo.

Jakkolwiek to zrobisz, nie będzie to przenośne, bo na na Linuksie (na Windowsie nie wiem, podejrzewam że podobnie) za podzielenie linii poleceń na argumenty odpowiada powłoka, a nie system operacyjny. Wołanie systemowe exec przyjmuje już listę stringów i tyle… W związku z tym, hipotetyczne rozwiązanie w Javie wiązałoby się z jakimś brzydkim FFI, w C# pewnie podobnie…

Czyli można przyjąć, ze to, co chcę zrobić, nie jest możliwe, a w aplikacji, której to było, pewnie za pomocą jakiejś funkcji WinAPI da się to otrzymać. Jednak brzydkie i nieprzenośne fikołki mnie nie interesują.

W ogóle nie znam WinAPI, ale jeżeli zamiast main jest faktycznie WinMain według https://cpp0x.pl/kursy/Kurs-WinAPI-C++/Podstawy/Podstawy-WinAPI/168 to faktycznie, może polecenie przekazywane jest bez żadnych zmian i dlatego móg być program, który uwzględnia białe znaki w poleceniu. Jak widać, do WinMain wchodzi jeden napis zamiast tablicy. Z drugiej strony, nie rozumiem, jak można zastąpić mail inną funkcją. Skąd system wie, że ma szukać WinMain, a nie main? Ja programowałem w Qt i QtCreator zawsze generuje krótki plik cpp, który zawiera normalną funkcję main, która ma góra 5 linii i wywołuje pierwszą formę.

Też pytanie po co w ogóle ci takie coś… Nie wyobrażam sobie rozsądnego zastosowania dla czegoś takiego…

Tworzyłem niejeden program, gdzie w linii poleceń podaje się parametry działania w stylu klucz=wartość , kolejność parametrów nieistotna. Póki co, nie miałem potrzeby w ten sposób ppodawać wartości z dwiema spacjami i na 95% nie będzie to potrtzebne, ale pytanie wynika z tego, że w celu poprawnego przetworzenia takiego polecenia, to i tak musze dostać jeden string, a potem przeanalizować po swojemu. Zauważyłem, że do programu wchodzi linia poleceń "na ślepo" podzielona spacjami, po prostu zrobiony string.split(' ') i do tego pominięte puste pozycje.

Na przykład takie polecenie:

PlikProgramu jakisnapis=qwe innynapis="napis ze spacja" nastepny="napis z wieloma spacjami"

Wydaje się, że powinienem dostać taką tablicę:

args[0] = "jakisnapis=qwe";
args[1] = "innynapis=\"napis";
args[2] = "ze";
args[3] = "spacja\"";
args[4] = "nastepny=\"napis";
args[5] = "z";
args[6] = "";
args[7] = "wieloma";
args[8] = "";
args[9] = "";
args[10] = "spacjami\"";

Po połączeniu wychodzi PlikProgramu jakisnapis=qwe innynapis="napis ze spacja" nastepny="napis z wieloma spacjami".

Ale dostaję taką:

args[0] = "jakisnapis=qwe";
args[1] = "innynapis=\"napis";
args[2] = "ze";
args[3] = "spacja\"";
args[4] = "nastepny=\"napis";
args[5] = "z";
args[6] = "wieloma";
args[7] = "spacjami\"";

Po połączeniu wychodzi PlikProgramu jakisnapis=qwe innynapis="napis ze spacja" nastepny="napis z wieloma spacjami".

Jeżeli dostanę to pierwsze, to nie byłoby tematu. Ale dostaję to drugie i stąd jest moje pytanie.

W C++ standardowo jest podobnie main(int argc, char *argv[]), ale czy wycina puste pozycje z tablicy, to nie wiem, nie sprawdzałem.

Na pytanie do czego mi to potrzebne prawdę mówiąc: W celu poprawnego przekazania wartości tekstowej przy implementacji papametryzowania w stylu klucz=wartość. Jeżeli nie jest to możliwe w standardowy sposób z zachowaniem cross-platform, to temat uważam za wyczerpany, bo i tak w ponad 95% nie będzie potrzeby podania wartości z dwiema spacjami, a jak już, to wtedy zastosuje dodatkowe znaki i po sprawie.

2

Nie jestem pewny jak to działa w Windowsie (może nawet inaczej w cmd.exe, a inaczej w PowerShellu), ale w POSIX (Linux, Mac), Czudzysłowy nie pojawiają się w linii poleceń, jeśli ich nie porzedzisz backslashem (lub nie będą w pojedynczym cudzysłowie), bo cudzysłów oznacza – traktuj to co jest wewnątrz jako jeden parametr (jeśli pojedyńczy, dodatkowo blokuje ekstrapolację zmiennych i globy). Tak więc jeśli masz linię

PlikProgramu jakisnapis=qwe innynapis="napis ze spacja" nastepny="napis z wieloma spacjami"

To linia poleceń wygląda następująco:

PlikProgramu
jakisnapis=qwe
innynapis=napis ze spacja
nastepny=napis z wieloma spacjami

Natomiast '"foo bar"' => "foo bar"
\"foo bar\" => "foo, bar"
itd…

0

w windowsie jest tak samo - to co jest w "" jest traktowane jako jedna całość. Dodatkowo w parametrach nie dostajesz cudzysłowów tylko czysty tekst

0

CMD działa tak, że piszesz cd "Nowy folder" - w "

1 użytkowników online, w tym zalogowanych: 0, gości: 1