2010-08-10 35 views
7

Tôi đã đọc thành viên mảng đầu tiên là argv sẽ luôn là tên chương trình.Xử lý `argv` trong chương trình dòng lệnh C

Bạn có bao giờ hữu ích khi thực hiện việc này không? Tôi đang học, vì vậy hãy tha thứ cho tôi nếu đó là một câu hỏi ngớ ngẩn.

Mọi người có bao giờ hủy chuyển đổi thành viên đầu tiên vì nó vô ích (và đặt lại argv thành ít hơn không?) Hoặc để nó có thực hành tốt nhất vì mọi người mong đợi nó sẽ luôn ở đó (và để nó hoạt động hộp với argc)?

+0

Related: http://stackoverflow.com/questions/3304845/qstringlist-qcoreapplicationarguments-in-what-situation-is-index-0-not-the ... thành viên đầu tiên của mảng argv sẽ không * luôn luôn * là tên chương trình – sje397

+0

@ sje397 Cảm ơn, thông tin tốt ở đó. – alex

Trả lời

7

Tôi đã đọc thành viên mảng đầu tiên của argv sẽ luôn là tên chương trình.

nên be. Cả C và C++ đều yêu cầu rằng nếu argc lớn hơn 0, argv[0] phải là tên chương trình hoặc chuỗi rỗng.

Một số hệ thống không nhất thiết tuân theo quy ước này trong mọi hoàn cảnh (trên Windows, ví dụ, bạn có thể sử dụng CreateProcess để tạo ra một quy trình mới và không vượt qua được tên chương trình trong các đối số dòng lệnh được sử dụng để cư argcargv).

Bạn có bao giờ hữu ích khi tiếp tục điều này không?

Chắc chắn. Ví dụ, nếu bạn muốn sinh ra một cá thể khác của mình, hoặc nếu bạn muốn in tên chương trình của mình (ví dụ như trong hướng dẫn sử dụng).

Mọi người có bao giờ unshift thành viên đầu tiên bởi vì nó vô dụng hay để nó có thực hành tốt nhất?

Không thay đổi đối số thực tế; người tiếp theo đến cùng có lẽ sẽ chờ họ ở dạng ban đầu.

+0

cho người tiếp theo! : D – Nyan

+0

Họ Unix của hệ thống các cuộc gọi hệ thống cũng cho phép 'argv [0]' được chỉ định độc lập với tệp để thoát. Ví dụ, shell đăng nhập thường có một '-' hàng đầu gắn liền với tên của nó bằng tiến trình đăng nhập bằng cách sử dụng tính năng này. – RBerteig

4

Để chính xác, argv[0] là bất kỳ thông tin nào được chuyển đến exec (2) thường là tên chương trình nhưng có thể là bất kỳ thứ gì.

Không hủy thay đổi vì có quá nhiều phụ thuộc ẩn được tính vào đó.

+0

Ẩn phụ thuộc? Không có hàm 'exec'. Có 'execve (2)' nhưng nó và gia đình của nó yêu cầu tên tệp mới làm đối số. Tại sao bạn 'execl' thực thi hiện tại? Điều đó sẽ chỉ reinitialize tất cả mọi thứ. – Potatoswatter

3

Dự kiến ​​argv [0] sẽ luôn chứa tên của tệp thực thi. Bởi vì điều này bạn không bao giờ nên loại bỏ nó.

Để xem liệu nó có hữu ích hay không, một lần sử dụng cho argv [0] là nếu bạn muốn ứng dụng của mình thay đổi hành vi dựa trên cách nó được gọi. Ví dụ:

Busybox, sử dụng điều này trên các hệ thống Linux được nhúng. Thông thường, bạn sẽ có một bản sao của tệp thực thi và tạo liên kết tượng trưng đến tệp thực thi với các tên khác nhau. ví dụ. cp, rm, ls, vv Busybox sau đó xác định chức năng nào sẽ thực hiện dựa trên nội dung của argv [0].

+0

Âm thanh thú vị, tuy nhiên, đó là một điều tiêu chuẩn để làm hoặc là nó giới hạn trong ứng dụng Busybox? – alex

+1

Đó là một kỹ thuật khá chuẩn. Cũng được sử dụng trong các ứng dụng như ccache và distcc. –

+0

IIRC, Nhiều tiện ích lõi "hai chữ" được triển khai theo cùng cách trên phiên bản Hệ thống III và BSD đầu tiên. (Tôi có cho thấy tuổi của tôi ở đây bằng cách thừa nhận có * sử dụng * Hệ thống III?) – RBerteig

3

Đối số đầu tiên không phải lúc nào cũng là tên chương trình - nó phụ thuộc vào cách nó được gọi (xem here).

Thông thường, argv[0] được sử dụng trong văn bản trợ giúp:

fprintf(stderr, "Usage: %s <foo> [bar]\n", argv[0]); 

Chuyển mảng không phải là terribly hữu ích và hiệu quả. Bạn cũng có thể bắt đầu sử dụng argv từ chỉ mục 1.

+0

@caf: ty 4 bản chỉnh sửa :) – sje397

+1

'++ argv; - argc; 'thay đổi hiệu quả mảng. Tôi nghĩ đó là ý nghĩa của OP. – Potatoswatter

0

nội dung của argv [0] không được định nghĩa bởi ANSI. argv có thể liệt kê:

main(int argc,char**argv) 
{ 
    while(argc--) 
    puts(*argv++); 
    return 0; 
} 
0

Từ ISO C99, §5.1.2.2.1,

Nếu giá trị của argc là lớn hơn không, các chuỗi được trỏ đến bởi argv [0] đại diện cho tên chương trình; argv [0] [0] phải là ký tự null nếu tên chương trình không có sẵn trong môi trường máy chủ.

Do đó, về việc triển khai phù hợp, bạn có thể dựa vào argv[0] như là tên của chương trình nếu bạn kiểm tra cho nó tồn tại trước (có nghĩa là, nếu bạn có thể khẳng định rằng argc > 0).

Các vấn đề liên quan