2010-02-25 37 views
11

Trong lớp cấu trúc dữ liệu mà tôi hiện đang dùng, chúng tôi đã được giao nhiệm vụ viết trình thu thập dữ liệu web bằng C++. Để cung cấp cho chúng tôi một khởi đầu, giáo sư đã cung cấp cho chúng tôi một chương trình để lấy nguồn từ một URL nhất định và một trình phân tích cú pháp HTML đơn giản để tách các thẻ ra. Chức năng chính của chương trình này chấp nhận các đối số và do đó sử dụng argc/argv. Các mã được sử dụng để kiểm tra cho các đối số như sau:Tại sao phải kiểm tra xem (* argv == NULL)?

// Process the arguments 
if (!strcmp(option, "-h")) 
{ 
    // do stuff... 
} 
else if (!strcmp(option, "")) 
{ 
    // do stuff... 
} 
else if (!strcmp(option, "-t")) 
{ 
    // do stuff... 
} 
else if (!strcmp(option, "-a")) 
{ 
    // do stuff... 
} 

if (*argv == NULL) 
{ 
    exit(1); 
} 

đâu "tùy chọn" đã được dân cư với các switch trong argv [1], và argv [2] và cao hơn có các đối số còn lại. Khối đầu tiên tôi hiểu tốt, nếu chuyển đổi bằng chuỗi làm bất cứ điều gì dựa trên chuyển đổi. Tôi tự hỏi mục đích của khối cuối cùng là gì.

Nó có thể là C++ của tôi là hơi gỉ, nhưng tôi dường như nhớ lại * argv là tương đương với argv [0], về cơ bản có nghĩa là nó đang kiểm tra để đảm bảo các đối số tồn tại. Ngoại trừ tôi đã được ấn tượng rằng argv [0] luôn luôn (ít nhất là trong hầu hết các triển khai) chứa tên của chương trình đang chạy. Nó xảy ra với tôi rằng argv [0] có thể là null nếu argc bằng 0, nhưng tìm kiếm xung quanh trên Google tôi không thể tìm thấy một bài duy nhất xác định có hay không mà thậm chí có thể.

Và vì vậy tôi chuyển sang bạn. Chính xác thì cuối cùng nếu khối kiểm tra là gì?

EDIT: Tôi đã đi với lý do được cung cấp trong các nhận xét của câu trả lời đã chọn, có thể cố ý gây ra argv [0] để trở thành NULL, hoặc bằng cách khác trở thành NULL dựa trên nền tảng cụ thể thực hiện chính.

+3

Lưu ý rằng 'argv' không phải là mảng mà là con trỏ. Điều đó có nghĩa là bạn hoàn toàn có thể nói 'argv ++' để lặp qua các tùy chọn. Bạn không phải sửa đổi giá trị của '* argv'. –

+0

Trong sự tò mò, lý do được đưa ra bởi giáo sư của bạn khi bạn hỏi anh/cô ấy về nó là gì? – Daniel

+0

Bây giờ, 5 năm sau, tôi sợ tôi thực sự không nhớ. Tôi dường như mơ hồ nhớ lại yêu cầu TA của tôi và lý do giống như trong các ý kiến ​​của câu trả lời được chấp nhận (xem EDIT trong câu hỏi), nhưng tôi có thể làm điều đó và chỉ nhớ tất cả sai. : P –

Trả lời

9

argc sẽ cung cấp cho bạn số đối số dòng lệnh được chuyển. Bạn không cần phải kiểm tra nội dung của argv quá xem nếu không có đủ đối số.

if (argc <= 1) { // The first arg will be the executable name 
    // print usage 
} 
+0

Tôi biết điều này, đoạn mã trên là mã được giáo sư của chúng tôi trao cho chúng tôi. Cá nhân, tôi luôn luôn kiểm tra chống lại argc. Tôi hỏi những gì là * argv == NULL thực sự kiểm tra? Ấn tượng của tôi là nó giống như kiểm tra argv [0] == NULL, mà theo như tôi biết là không thể, vậy tại sao lại kiểm tra nó? –

+3

@Shaun: Có, '* argv' giống hệt' argv [0] '. Điều này thường không thể thực hiện được khi bạn đang chạy ứng dụng từ một trình bao bình thường. Nhưng tôi nghĩ * có thể xảy ra nếu bạn thực hiện một tiến trình trực tiếp từ một chương trình khác bằng cách sử dụng lệnh gọi hệ thống 'exec' và truyền các mảng một cách thủ công. –

+0

Tôi nghĩ argv [0] luôn luôn chứa tên của chương trình mặc dù, vậy tại sao kiểm tra để xem nếu nó là NULL? –

4

Hãy nhớ cách C di động, có thể không phải lúc nào cũng chạy trên nền tảng chuẩn như Windows hoặc Unix. Có lẽ đó là một số vi mã bên trong máy giặt của bạn chạy trên một số môi trường giá rẻ, bị tấn công. Như vậy, thực hành tốt để đảm bảo một con trỏ không phải là null trước khi dereferencing nó, mà có thể đã dẫn đến câu hỏi.

Mặc dù vậy, bạn chính xác. * argv cũng giống như argv [0], và argv là được cho là để được khởi tạo bởi môi trường, nếu nó được cung cấp.

+4

'Có lẽ đó là một số vi mã bên trong máy giặt của bạn' - Tuyệt vời, bây giờ tôi đang chờ đợi thông báo "Rất tiếc, bạn phải cập nhật 'Adobe Flash' lên phiên bản mới nhất để tham gia chu kỳ xả." –

+2

Rửa màu xanh chết chóc: P – MSalters

10

3.6.1/2:

Nếu argc là khác không những lập luận được quy định trong argv [0] mặc dù ... và argv [0] sẽ là con trỏ đối với ký tự ban đầu của NTMBS đại diện cho tên được sử dụng để gọi chương trình hoặc "". Giá trị của argc sẽ không âm. Giá trị của argv[argc] phải bằng 0.

Mỏ nhấn mạnh. argc chỉ được đảm bảo không tiêu cực, không phải không khác.

Đây là mục nhập chính. Cũng có thể là //do stuff sửa đổi giá trị của argv hoặc nội dung của mảng mà nó trỏ đến. Nó không hoàn toàn không nghe về mã xử lý tùy chọn để thay đổi giá trị khỏi argv khi nó xử lý chúng.Do đó, thử nghiệm cho *argv == null có thể kiểm tra xem có bất kỳ đối số dòng lệnh nào không, sau khi các tùy chọn đã bị xóa hoặc bỏ qua. Bạn sẽ phải xem phần còn lại của mã.

4

chỉ là một suy đoán.

nếu giáo sư của bạn đề cập đến điều này thì sao ??

while(*++argv !=NULL) 

    printf("%s\n",*argv); 
Các vấn đề liên quan