Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Linux ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ…Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 13

Автор Роббинс ΠΡ€Π½ΠΎΠ»ΡŒΠ΄

7.Β ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΌΠΎΠ³ΡƒΡ‚ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚ΡŒ Π΄Π»ΠΈΠ½Π½Ρ‹ΠΌ опциям Π½Π°Ρ‡ΠΈΠ½Π°Ρ‚ΡŒΡΡ с ΠΎΠ΄Π½ΠΎΠΉ Ρ‡Π΅Ρ€Ρ‚ΠΎΡ‡ΠΊΠΈ (Π­Ρ‚ΠΎ Ρ‚ΠΈΠΏΠΈΡ‡Π½ΠΎ для ΠΌΠ½ΠΎΠ³ΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ X Window.)

МногоС ΠΈΠ· этого станСт яснСС, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ·ΠΆΠ΅ Π² этой Π³Π»Π°Π²Π΅ ΠΌΡ‹ рассмотрим

getopt_long()
.

GNU Coding Standards удСляСт Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ мСсто ΠΏΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»Π΅Π½ΠΈΡŽ всСх Π΄Π»ΠΈΠ½Π½Ρ‹Ρ… ΠΈ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΈΡ… ΠΎΠΏΡ†ΠΈΠΉ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°ΠΌΠΈ GNU. Если Π²Ρ‹ ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΡƒΡŽ Π΄Π»ΠΈΠ½Π½Ρ‹Π΅ ΠΎΠΏΡ†ΠΈΠΈ, посмотритС, Π½Π΅Ρ‚ Π»ΠΈ ΡƒΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΡ…ΡΡ ΠΈΠΌΠ΅Π½ ΠΎΠΏΡ†ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠΌΠ΅Π»ΠΎ Π±Ρ‹ смысл ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ Π²Π°ΠΌ.

2.2. Базовая ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π½Π° Π‘ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ доступ ΠΊ своим Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки Ρ‡Π΅Ρ€Π΅Π· ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹

argc
ΠΈ
argv
. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€
argc
являСтся Ρ†Π΅Π»Ρ‹ΠΌ, ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΌ число ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ…ΡΡ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ², Π²ΠΊΠ»ΡŽΡ‡Π°Ρ имя ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹. Π•ΡΡ‚ΡŒ Π΄Π²Π° ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Ρ… способа опрСдСлСния
main()
, ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‰ΠΈΡ…ΡΡ способом объявлСния
argc
:

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

{Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β {

...Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β  ...

}Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β Β  }

ΠŸΡ€Π°ΠΊΡ‚ΠΈΡ‡Π΅ΡΠΊΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ двумя этими объявлСниями Π½Π΅Ρ‚ Ρ€Π°Π·Π½ΠΈΡ†Ρ‹, хотя ΠΏΠ΅Ρ€Π²ΠΎΠ΅ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎ Π±ΠΎΠ»Π΅Π΅ понятно:

argc
являСтся массивом ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° символы. А Π²Ρ‚ΠΎΡ€ΠΎΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ тСхничСски Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ, это Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ. На рис. 2.2 ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½Π° эта ситуация.

Linux ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ… - img_2.png

Рис. 2.2. ΠŸΠ°ΠΌΡΡ‚ΡŒ для

argc

По соглашСнию,

argv[0]
являСтся ΠΈΠΌΠ΅Π½Π΅ΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. (Π”Π΅Ρ‚Π°Π»ΠΈ см. Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 9.1.4.3. «ИмСна ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ ΠΈ
argv[0]
Β».) ΠŸΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ элСмСнты ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки. ПослСдним элСмСнтом массива
argv
являСтся ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ
NULL
.

argc
ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, сколько имССтся Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²; ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π² Π‘ индСксы ΠΎΡ‚ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ с нуля, Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ '
argv[argc] == NULL
' всСгда Π²Π΅Ρ€Π½ΠΎ. Из-Π·Π° этого, особСнно Π² ΠΊΠΎΠ΄Π΅ для Unix, Π²Ρ‹ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ способы ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ окончания списка Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ², Ρ‚Π°ΠΊΠΈΠ΅, ΠΊΠ°ΠΊ Ρ†ΠΈΠΊΠ» с ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΎΠΉ, Ρ‡Ρ‚ΠΎ счСтчик прСвысил
argc
, ΠΈΠ»ΠΈ '
argv[i] == 0
', ΠΈΠ»ΠΈ '
*argv != NULL
' ΠΈ Ρ‚.Π΄. Они всС эквивалСнтны.

2.2.1. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°

echo
V7

Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки являСтся ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° V7

echo,
ΠΏΠ΅Ρ‡Π°Ρ‚Π°ΡŽΡ‰Π°Ρ свои Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Π² стандартный Π²Ρ‹Π²ΠΎΠ΄, раздСляя ΠΈΡ… ΠΏΡ€ΠΎΠ±Π΅Π»Π°ΠΌΠΈ ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ°Ρ символом ΠΊΠΎΠ½Ρ†Π° строки. Если ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ являСтся
-n
, Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰ΠΈΠΉ символ Π½ΠΎΠ²ΠΎΠΉ строки опускаСтся. (Π­Ρ‚ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΏΡ€ΠΈΠ³Π»Π°ΡˆΠ΅Π½ΠΈΠΉ ΠΈΠ· сцСнариСв ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΈ.) Π’ΠΎΡ‚ ΠΊΠΎΠ΄ [28]:

1Β  #include <stdio.h>

2

3Β  main(argc, argv) /*int main(int argc, char **argv)*/

4Β  int argc;

5Β  char *argv[];

6Β  {

7Β Β  register int i, nflg;

8

9Β Β  nflg = 0;

10Β  if (argc > 1 && argv[1][0] == && argv[1][1] == 'n') {

11Β Β  nflg++;

12Β Β Β argc--;

13Β Β Β argv++;

14Β Β }

15Β Β for (i=1; i<argc; i++) {

16Β Β  fputs(argv[i], stdout);

17Β Β  if (i < argc-1)

18Β Β  putchar(' ');

19Β Β }

20Β Β if (nflg == 0)

21Β Β  putchar('\n');

22Β Β exit(0);

23Β }

ВсСго 23 строки! Π—Π΄Π΅ΡΡŒ Π΅ΡΡ‚ΡŒ Π΄Π²Π° интСрСсных ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°. Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΠ΅

argc
ΠΈ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ΅ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅
argv
(строки 12 ΠΈ 13) ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌ способом пропуска Π½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹Ρ… Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ². Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° наличия
-n
(строка 10) являСтся ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½ΠΈΠ΅ΠΌ.
-no-newline-at-the-end
Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚. (ΠžΡ‚ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠΉΡ‚Π΅ ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ это!)

Π ΡƒΡ‡Π½ΠΎΠΉ Ρ€Π°Π·Π±ΠΎΡ€ ΠΎΠΏΡ†ΠΈΠΉ ΠΎΠ±Ρ‹Ρ‡Π΅Π½ для ΠΊΠΎΠ΄Π° V7, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ функция

getopt()
Π½Π΅ Π±Ρ‹Π»Π° Π΅Ρ‰Π΅ ΠΏΡ€ΠΈΠ΄ΡƒΠΌΠ°Π½Π°.

НаконСц, здСсь ΠΈ Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… мСстах ΠΏΠΎ всСй ΠΊΠ½ΠΈΠ³Π΅, ΠΌΡ‹ Π²ΠΈΠ΄ΠΈΠΌ использованиС ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ³ΠΎ слова register. Одно врСмя это ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово Π΄Π°Π²Π°Π»ΠΎ компилятору подсказку, Ρ‡Ρ‚ΠΎ данная пСрСмСнная Π΄ΠΎΠ»ΠΆΠ½Π° ΠΏΠΎ возмоТности Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Ρ‚ΡŒΡΡ Π² рСгистрС процСссора. Π’Π΅ΠΏΠ΅Ρ€ΡŒ это ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово устарСло; соврСмСнныС компиляторы всС ΠΎΡΠ½ΠΎΠ²Ρ‹Π²Π°ΡŽΡ‚ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Π² рСгистрах Π½Π° Π°Π½Π°Π»ΠΈΠ·Π΅ исходного ΠΊΠΎΠ΄Π°, игнорируя ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово

register
. ΠœΡ‹ Ρ€Π΅ΡˆΠΈΠ»ΠΈ ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠΉ это слово ΠΊΠΎΠ΄, ΠΊΠ°ΠΊ Π΅ΡΡ‚ΡŒ, Π½ΠΎ Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π·Π½Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΎ большС Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ примСнСния. [29]

2.3. Π Π°Π·Π±ΠΎΡ€ ΠΎΠΏΡ†ΠΈΠΉ:

getopt()
ΠΈ
getopt_long()

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Π² 1980-Ρ… Π³Ρ€ΡƒΠΏΠΏΠ° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ Unix для System III Π² AT&T Π·Π°ΠΌΠ΅Ρ‚ΠΈΠ»Π°, Ρ‡Ρ‚ΠΎ каТдая ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Unix использовала для Ρ€Π°Π·Π±ΠΎΡ€Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² свои собствСнныС ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΠΈ. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Π»Π΅Π³Ρ‡ΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΈ программистов, ΠΎΠ½ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π»ΠΈ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ ΠΈΠ· пСрСчислСнных Ρ€Π°Π½Π΅Π΅ соглашСний. (Π₯отя ΠΈΠ·Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² System III справки для intro(1) Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΌΠ΅Π½Π΅Π΅ Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ, Ρ‡Π΅ΠΌ Π² стандартС POSIX.)

Π“Ρ€ΡƒΠΏΠΏΠ° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ Unix Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π»Π° Ρ‚Π°ΠΊΠΆΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ

getopt()
, вмСстС с нСсколькими внСшними ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΏΡ€ΠΎΡΡ‚ΠΈΡ‚ΡŒ написаниС ΠΊΠΎΠ΄Π°, ΠΏΡ€ΠΈΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰Π΅Π³ΠΎΡΡ стандартных соглашСний. Ѐункция GNU
getopt_long()
прСдоставляСт ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΡƒΡŽ с
getopt()
Π²Π΅Ρ€ΡΠΈΡŽ, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ Ρ€Π°Π·Π±ΠΎΡ€ Π΄Π»ΠΈΠ½Π½Ρ‹Ρ… ΠΎΠΏΡ†ΠΈΠΉ Π² описанной Ρ€Π°Π½Π΅Π΅ Ρ„ΠΎΡ€ΠΌΠ΅.

2.3.1. ΠžΠΏΡ†ΠΈΠΈ с ΠΎΠ΄Π½ΠΈΠΌ символом

Ѐункция

getopt()
объявлСна ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

#include <unistd.h> /*POSIX*/

int getopt(int argc, char *const argv[], const char *optstring);

extern char *optarg;

extern int optind, opterr, optopt;

АргумСнты

argc
ΠΈ
argv
ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ нСпосрСдствСнно ΠΎΡ‚
main()
.
optstring
являСтся строкой символов ΠΎΠΏΡ†ΠΈΠΉ. Если Π·Π° ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ Π±ΡƒΠΊΠ²ΠΎΠΉ Π² строкС слСдуСт Π΄Π²ΠΎΠ΅Ρ‚ΠΎΡ‡ΠΈΠ΅, эта опция ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ наличия Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°.