2012-02-14 33 views
5

Đây là một chương trình C đơn giản mà in số lượng đối số dòng lệnh được truyền cho nó:Command Line Đối số Đếm

#include <stdio.h> 

int main(int argc, char *argv[]) 
{ 
    printf("%d\n", argc); 
} 

Khi tôi cung cấp cho các đầu vào

file_name * 

It in 623 thay vì 2 trong máy tính của tôi (hệ điều hành Windows 7). Nhưng nó cho đầu ra chính xác trong các trường hợp khác. Có phải * một ký tự dành riêng cho đối số dòng lệnh không? Lưu ý chương trình này cung cấp cho sản lượng chính xác cho các đầu vào sau:

file_name *Rafi 

Output = 2

+0

@pmg: Tôi đã sửa đổi các câu hỏi để 'file_name' là một từ chứ không phải là hai ... mà có lẽ những gì Rafi dự định. Nếu không, anh ấy sẽ chỉnh sửa lại và chúng tôi có thể nghi ngờ về 2 so với 3 lần nữa. –

+0

Trình biên dịch C/C++ của Microsoft ('cl.exe') sẽ in 2 trong cả hai ví dụ của bạn. Bạn đang sử dụng một trình biên dịch khác? – user7116

+0

Yah .. bạn là đúng :) @ Jonathan –

Trả lời

10

Trên một dòng lệnh Unix, vỏ có trách nhiệm xử lý các ký tự đại diện. yourapp * sẽ chạy yourapp và chuyển tên của TẤT CẢ các tệp không ẩn trong thư mục hiện tại làm đối số. Trong trường hợp của bạn, đó là 622 tệp (623 = 622 tệp + tên của chương trình).

Trên Windows, các ứng dụng chịu trách nhiệm phân tích cú pháp ký tự đại diện, vì vậy argc là 2, 1 cho tên chương trình (argv [0]) và 1 cho ký tự đại diện (argv [1] = *);

+0

Cảm ơn bạn :) Tôi đã suy nghĩ rằng 623 là gì, nhưng một lỗi :) –

+0

Tôi chưa bao giờ mới rằng Windows thực hiện điều này "sai" :) –

+0

@ Brian: nó không phải là 'sai' , khác biệt. Phong cách của Windows làm cho những thứ như 'ren * .jpg * .jpeg' có thể, trong khi đó là v.diff khó trên một hệ thống Unix. –

3

Đó * được mở rộng bằng vỏ hoặc thư viện runtime (cựu trên nixes *, sau này trên Windowses), và thay vì đen * bạn sẽ có được tên của tất cả các tập tin trong thư mục làm việc hiện hành.

1

Vấn đề là vỏ mở rộng * vào tất cả tên tệp (không bắt đầu bằng số .) trong thư mục hiện tại. Đây là tất cả về vỏ và rất ít để làm với chương trình C.

Giá trị của argc bao gồm 1 cho tên riêng của chương trình, cộng với một cho mỗi đối số được chuyển bởi trình bao.

Hãy thử:

filename * 
filename '*' 

Việc đầu tiên sẽ cung cấp cho bạn 623 (cho hoặc mất - nhưng đó là thời gian bạn làm sạch thư mục đó!). Thứ hai sẽ cung cấp cho bạn 2.

2

Như những người khác đã đề cập, bạn sẽ nhận được 'mở rộng ký tự đại diện vỏ' hoặc 'globbing' ở đó * được sử dụng làm ký tự đại diện để khớp với tên tệp để đặt trong mảng argv.

Trên hệ thống Unix, trình bao này được thực hiện bởi trình bao và không có gì (hoặc ít) để thực hiện với thời gian chạy C.

Trên hệ thống Windows, chức năng này không được thực hiện bởi trình bao (trừ khi có thể nếu bạn đang sử dụng một số thay thế vỏ giống Unix như Cygwin). Chức năng globbing có thể hoặc không thể được thực hiện bằng cách khởi tạo thời gian chạy C tùy thuộc vào những gì các công cụ và/hoặc mối liên kết tùy chọn bạn sử dụng:

  • nếu bạn đang sử dụng trình biên dịch của Microsoft, thời gian chạy C sẽ không thực hiện globbing theo mặc định và bạn sẽ nhận được một giá trị argc của 2 trong ví dụ của bạn. Tuy nhiên, nếu bạn yêu cầu trình liên kết liên kết trong setargv.obj (hoặc wsetargv.obj nếu bạn có một bản dựng Unicode), thì phần tử được thêm vào khởi tạo thời gian chạy và bạn sẽ nhận được hành vi tương tự như của Unix.setargv.obj đã được phân phối với MSVC miễn là tôi có thể nhớ, nhưng nó vẫn còn ít được biết đến. Tôi tin rằng hầu hết các chương trình Windows thực hiện mở rộng ký tự đại diện riêng của họ.

  • nếu bạn đang sử dụng chuỗi công cụ MinGW/GCC, thời gian chạy C sẽ thực hiện globbing trước khi gọi main() (ít nhất là đối với MinGW 4.6.1 - Tôi nghi ngờ nó nằm trong MinGW trong một thời gian dài). Tôi nghĩ rằng MinGW có thể không thực hiện globbing cho các chương trình GUI. Bạn có thể vô hiệu hóa hành vi globbing MinGW với một trong các cách sau:

    1. định nghĩa một biến toàn cục có tên _CRT_glob và khởi tạo nó để 0:

      int _CRT_glob = 0; 
      
    2. liên kết trong tập tin lib/CRT_noglob.o đối tượng (Tôi nghĩ rằng sức mạnh này có trật tự phụ thuộc - bạn có thể cần phải đặt nó trước khi bất kỳ thư viện):

      gcc c:/mingw/lib/CRT_noglob.o main.o -o main.exe 
      
+0

Một thông tin tuyệt vời w.r.t. 'setargv.obj', rất hữu ích, cảm ơn! – vsizikov

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