20.4 — Argumenty wiersza poleceń

Potrzeba argumentów wiersza poleceń

Jak nauczyłeś się na lekcji 0.5 — Wprowadzenie do kompilatora, linkera i bibliotek podczas kompilacji i połącz swój program, wynikiem będzie plik wykonywalny. Kiedy program jest uruchamiany, jego wykonanie rozpoczyna się od początku funkcji zwanej main(). Do tego momentu deklarowaliśmy funkcję main w następujący sposób:

int main()

Zauważ, że ta wersja funkcji main() nie przyjmuje żadnych parametrów. Jednak wiele programów wymaga pewnego rodzaju danych wejściowych do pracy. Załóżmy na przykład, że piszesz program o nazwie Thumbnail, który wczytuje plik obrazu, a następnie tworzy miniaturę (mniejszą wersję obrazu). Skąd Thumbnail będzie wiedział, który obraz przeczytać i przetworzyć? Użytkownik musi mieć jakiś sposób, aby powiedzieć programowi, który plik ma otworzyć. Aby to zrobić, możesz zastosować następujące podejście:

// Program: Thumbnail
#include <iostream>
#include <string>

int main()
{
    std::cout << "Please enter an image filename to create a thumbnail for: ";
    std::string filename{};
    std::cin >> filename;

    // open image file
    // create thumbnail
    // output thumbnail
}

Jednakże istnieje potencjalny problem z tym podejściem. Za każdym razem, gdy program jest uruchamiany, będzie on czekał, aż użytkownik wprowadzi dane wejściowe. Może to nie stanowić problemu, jeśli uruchomisz ten program ręcznie z wiersza poleceń. Jest to jednak problematyczne w innych przypadkach, np. gdy chcesz uruchomić ten program na wielu plikach lub aby ten program był uruchamiany przez inny program.

Przyjrzyjmy się tym przypadkom bliżej.

Rozważmy przypadek, w którym chcesz utworzyć miniatury wszystkich plików obrazów w danym katalogu. Jak byś to zrobił? Można uruchomić ten program tyle razy, ile obrazów znajduje się w katalogu, wpisując ręcznie nazwę każdego pliku. Jeśli jednak byłyby setki zdjęć, mogłoby to zająć cały dzień! Dobrym rozwiązaniem byłoby napisanie programu, który będzie przeglądał każdą nazwę pliku w katalogu i wywoływał Thumbnail raz dla każdego pliku.

Rozważmy teraz przypadek, gdy prowadzisz witrynę internetową i chcesz, aby Twoja witryna tworzyła miniaturę za każdym razem, gdy użytkownik prześle obraz do Twojej witryny. Ten program nie jest skonfigurowany do akceptowania danych wejściowych z Internetu, więc jak w tym przypadku osoba przesyłająca miałaby wprowadzić nazwę pliku? Dobrym rozwiązaniem byłoby automatyczne wywoływanie przez serwer WWW Thumbnail po przesłaniu.

W obu przypadkach naprawdę potrzebujemy sposobu, aby zewnętrzny programu przekazywał nazwę pliku jako dane wejściowe do naszego programu Thumbnail po uruchomieniu Thumbnail, zamiast czekać, aż użytkownik wprowadzi nazwa pliku po jego uruchomieniu.

Argumenty wiersza poleceń są opcjonalnymi argumentami w postaci łańcuchów, które system operacyjny przekazuje do programu podczas jego uruchamiania. Program może następnie użyć ich jako danych wejściowych (lub zignorować je). Podobnie jak parametry funkcji umożliwiają funkcji dostarczanie danych wejściowych do innej funkcji, argumenty wiersza poleceń umożliwiają ludziom lub programom dostarczanie danych wejściowych do programu.

Przekazywanie argumentów wiersza poleceń

Programy wykonywalne można uruchamiać w wierszu poleceń, wywołując je według nazwy. Na przykład, aby uruchomić plik wykonywalny „WordCount”, który znajduje się w bieżącym katalogu komputera z systemem Windows, można wpisać:

WordCount

Odpowiedni wiersz poleceń w systemie operacyjnym opartym na systemie Unix będzie wyglądał następująco:

./WordCount

Aby przekazać argumenty wiersza poleceń do programu WordCount, po prostu wyszczególniamy argumenty wiersza poleceń po nazwie pliku wykonywalnego:

WordCount Myfile.txt

Teraz, gdy wykonywany jest program WordCount, Mójplik.txt zostanie podany jako argument wiersza poleceń. Program może mieć wiele argumentów wiersza poleceń oddzielonych spacjami:

WordCount Myfile.txt Myotherfile.txt

Jeśli uruchamiasz program z poziomu IDE, IDE powinno umożliwiać wprowadzanie argumentów wiersza poleceń.

W Microsoft Visual Studio kliknij prawym przyciskiem myszy projekt w eksploratorze rozwiązań, a następnie wybierz właściwości. Otwórz element drzewa „Właściwości konfiguracji” i wybierz „Debugowanie”. W prawym okienku znajduje się wiersz o nazwie „Argumenty poleceń”. Możesz tam wprowadzić argumenty wiersza poleceń do przetestowania, a zostaną one automatycznie przekazane do programu po jego uruchomieniu.

W Code::Blocks wybierz „Projekt -> Ustaw argumenty programu”.

Używanie argumentów wiersza poleceń

Teraz, gdy wiesz, jak dostarczać argumenty wiersza poleceń do programu, następnym krokiem jest uzyskanie do nich dostępu z poziomu naszego programu C++. Aby to zrobić, używamy innej formy funkcji main() niż widzieliśmy wcześniej. Ta nowa forma funkcji main() przyjmuje dwa argumenty (zgodnie z konwencją nazywane argc i argv) w następujący sposób:

int main(int argc, char* argv[])

Czasami można ją również spotkać w postaci:

int main(int argc, char** argv)

Mimo że są one traktowane identycznie, wolimy pierwszą reprezentację, ponieważ jest ona intuicyjnie łatwiejsza do zrozumienia.

argc to parametr typu całkowitego zawierający liczbę argumentów przekazanych do programu (pomyśl: argc = argument cilość). argc zawsze będzie wynosić co najmniej 1, ponieważ pierwszym argumentem jest zawsze nazwa samego programu. Każdy argument wiersza poleceń podany przez użytkownika spowoduje zwiększenie argc o 1.

argv to miejsce, w którym przechowywane są rzeczywiste wartości argumentów (pomyśl: argv = argument values, chociaż właściwa nazwa to „wektory argumentów”). Chociaż deklaracja argv wygląda onieśmielająco, argv jest w rzeczywistości tablicą wskaźników char w stylu C (z których każdy wskazuje na ciąg znaków w stylu C). Długość tej tablicy to argc.

Napiszmy krótki program o nazwie „MyArgs”, aby wydrukować wartości wszystkich parametrów wiersza poleceń:

// Program: MyArgs
#include <iostream>

int main(int argc, char* argv[])
{
    std::cout << "There are " << argc << " arguments:\n";

    // Loop through each argument and print its number and value
    for (int count{ 0 }; count < argc; ++count)
    {
        std::cout << count << ' ' << argv[count] << '\n';
    }

    return 0;
}

Teraz, gdy wywołamy ten program (MyArgs) z argumentami wiersza poleceń „Mójplik.txt” i „100”, wynik będzie następujący:

There are 3 arguments:
0 C:\MyArgs
1 Myfile.txt
2 100

Argument 0 to ścieżka i nazwa aktualnie uruchomiony program. Argumenty 1 i 2 w tym przypadku to dwa parametry wiersza poleceń, które przekazaliśmy.

Zauważ, że nie możemy używać pętli for opartej na zakresach do iteracji argv, ponieważ pętle for oparte na zakresach nie działają na uszkodzonych tablicach w stylu C.

Obsługa argumentów numerycznych

Argumenty wiersza poleceń są zawsze przekazywane jako ciągów znaków, nawet jeśli podana wartość ma charakter numeryczny. Aby użyć argumentu wiersza poleceń jako liczby, należy przekonwertować go z ciągu znaków na liczbę. Niestety w C++ jest to trochę trudniejsze, niż powinno.

Sposób, w jaki można to zrobić w C++, jest następujący:

#include <iostream>
#include <sstream> // for std::stringstream
#include <string>

int main(int argc, char* argv[])
{
	if (argc <= 1)
	{
		// On some operating systems, argv[0] can end up as an empty string instead of the program's name.
		// We'll conditionalize our response on whether argv[0] is empty or not.
		if (argv[0])
			std::cout << "Usage: " << argv[0] << " <number>" << '\n';
		else
			std::cout << "Usage: <program name> <number>" << '\n';
            
		return 1;
	}

	std::stringstream convert{ argv[1] }; // set up a stringstream variable named convert, initialized with the input from argv[1]

	int myint{};
	if (!(convert >> myint)) // do the conversion
		myint = 0; // if conversion fails, set myint to a default value

	std::cout << "Got integer: " << myint << '\n';

	return 0;
}

Po uruchomieniu z wejściem „567” program wypisuje:

Got integer: 567

std::stringstream działa podobnie jak std::cin. W tym przypadku inicjujemy go wartością argv[1], abyśmy mogli użyć operatora>> do wyodrębnienia wartości do zmiennej całkowitej (tak samo jak w przypadku std::cin).

Więcej o std::stringstream porozmawiamy w przyszłym rozdziale.

System operacyjny najpierw analizuje argumenty wiersza poleceń

Kiedy wpiszesz coś w wierszu poleceń (lub uruchom program z IDE), za przetłumaczenie i przekierowanie tego żądania w razie potrzeby odpowiada system operacyjny. Obejmuje to nie tylko uruchomienie pliku wykonywalnego, ale także parsowanie argumentów w celu ustalenia, w jaki sposób powinny być one obsługiwane i przekazywane do aplikacji.

Ogólnie rzecz biorąc, systemy operacyjne mają specjalne zasady dotyczące obsługi znaków specjalnych, takich jak cudzysłowy i ukośniki odwrotne.

Na przykład:

MyArgs Hello world!

drukuje:

There are 3 arguments:
0 C:\MyArgs
1 Hello
2 world!

Zazwyczaj ciągi znaków podane w podwójnych cudzysłowach są uważane za część tego samego string:

MyArgs "Hello world!"

drukuje:

There are 2 arguments:
0 C:\MyArgs
1 Hello world!

Większość systemów operacyjnych pozwala na dołączenie dosłownego podwójnego cudzysłowu poprzez ukośnik odwrotny do podwójnego cudzysłowu:

MyArgs \"Hello world!\"

drukuje:

There are 3 arguments:
0 C:\MyArgs
1 "Hello
2 world!"

Inne znaki mogą również wymagać ukośnika odwrotnego lub zmiany znaczenia, w zależności od tego, jak interpretuje je Twój system operacyjny.

Wnioski

Argumenty wiersza poleceń zapewniają użytkownikom lub innym programom świetny sposób przekazywania danych wejściowych do programu podczas uruchamiania. Rozważ wprowadzenie wszelkich danych wejściowych, których program potrzebuje podczas uruchamiania, aby móc obsługiwać parametr wiersza poleceń. Jeśli wiersz poleceń nie zostanie przekazany, zawsze możesz to wykryć i poprosić użytkownika o wprowadzenie danych. W ten sposób Twój program może działać w dowolny sposób.

guest
Twój adres e-mail nie zostanie wyświetlony
Znalazłeś błąd? Zostaw komentarz powyżej!
Komentarze związane z poprawkami zostaną usunięte po przetworzeniu, aby pomóc zmniejszyć bałagan. Dziękujemy za pomoc w ulepszaniu witryny dla wszystkich!
Awatary z https://gravatar.com/ są połączone z podanym adresem e-mail.
Powiadamiaj mnie o odpowiedziach:  
229 Komentarze
Najnowsze
Najstarsze Najczęściej głosowane
Wbudowane opinie
Wyświetl wszystkie komentarze