2009-09-29 49 views
6

Hãy để tôi bắt đầu bằng cách nói điều này được liên kết với bài tập về nhà. Tuy nhiên, đây là một phần rất nhỏ và không đáng kể trong nhiệm vụ.Đọc đối số dòng lệnh sau '<' trong C

Chương trình C nhận đầu vào thông qua đối số dòng lệnh nhưng nó cần phải được theo hình thức:

$ ./program < input 

thế nào, tôi sẽ đi về việc nhận đầu vào đó như là một chuỗi? Mỗi khi tôi cố gắng in ra đối số thứ 3 từ argv, tôi nhận được thông báo này:

đầu vào: Không có tệp hoặc thư mục nào.

Trả lời

21

< là chuyển hướng trình bao - nó được xử lý bên ngoài chương trình của bạn. Những gì bạn sẽ thấy là nội dung của tên tệp 'đầu vào' được gửi tới luồng đầu vào chuẩn của bạn. Đây là cách phổ biến cho các chương trình hoạt động, mặc dù chúng thường xử lý việc được cấp tên tệp, ví dụ: sed.

Nếu tôi phải đoán tôi sẽ nghĩ rằng:

input: No such file or directory. 

đến từ vỏ, vì nó không thể mở các tập tin được chỉ định: "đầu vào".

Mặt khác, nếu bạn thực sự muốn < input làm đối số cho chương trình của mình, bạn có thể thoát hoặc báo giá chúng để vỏ sẽ không diễn giải chúng. (Thoát khỏi trái như một bài tập cho người đọc :-)).

+0

Wow, 6 phiếu trong phút đầu tiên! –

+2

Đó là một cảnh quay bạn có ở đó, ông Eastwood. –

3

Điều gì xảy ra sau khi < không phải là đối số dòng lệnh. Nội dung của tệp sẽ được trình bao bọc vào chương trình của bạn.

Tất cả những gì bạn cần làm là đọc từ stdin và bạn sẽ nhận được nội dung của tệp.

5

Trên hệ thống * nix, sẽ không có yếu tố thứ ba là argv. Nếu bạn thực hiện lệnh mà trên hầu như bất kỳ shell Unix-like, nó sẽ tương tự như làm điều này:

cat input | ./program 

Vì vậy ./program bạn chỉ có một phần tử trong argv, nhưng nó stdin là file input, vì vậy để đọc tệp bạn vừa đọc từ stdin. Lưu ý rằng đây là một cách hoàn toàn hợp lệ để thiết kế chương trình của bạn. Nhiều chương trình Unix đọc từ đầu vào tiêu chuẩn nếu không có tệp nào được cung cấp, để bạn có thể đặt đường ống vào đầu vào từ các chương trình khác (hoặc trong trường hợp này là từ tệp).

+1

Không chỉ trên các hệ thống * nix. DOS/Windows và OS/2 xử lý điều này theo cùng một cách. Và nhân tiện, giải thích toán tử '<' shell với '|' không thực sự làm rõ vấn đề ;-) –

+0

Nó có thể không làm cho nó ngay lập tức rõ ràng hơn, nhưng nó cho thấy rõ ràng hơn rằng './program' không được đưa ra bất kỳ đối số. –

+0

Điều này thực sự không đúng cho DOS - trong DOS toàn bộ dòng lệnh (với chuyển hướng) được chuyển đến chương trình và nó có trách nhiệm mở tệp và như vậy. Tất nhiên, nếu bạn sử dụng trình biên dịch C, trình khởi động của trình biên dịch chạy trước chính sẽ làm việc này cho bạn ... –

10

Cú pháp ./program < input là cú pháp shell đặc biệt cho biết "Chuyển hướng mọi thứ trong tệp có tên input thành mục nhập chuẩn của chương trình".

Để đọc đầu vào, chương trình của bạn chỉ cần sử dụng chức năng đọc đầu vào tiêu chuẩn, dòng fgets hoặc scanf.

+0

* "Để đọc đầu vào, chương trình của bạn chỉ cần sử dụng các chức năng đọc đầu vào tiêu chuẩn, dòng' fgets' hoặc 'scanf'." * Cụ thể, trên luồng 'stdin'. –

+1

@ T.J. 'Scanf()' hoạt động trên luồng nào khác? : P –

3

Bạn cần phải thoát khỏi '<', nếu không shell sẽ phân tích cú pháp và chương trình sẽ không nhận được nó trong dòng lệnh.

Nếu bạn đang sử dụng bash, sau đó:

./program '<' input 

hoặc

./program \< input 

vỏ khác có thể làm điều đó khác nhau (mặc định ví dụ như Windows, cmd.exe, sử dụng ^ như nhân vật chạy thoát, không \).

-2

Bạn có thể lấy nó bằng cách đọc stdin.

0

Đây là một điều shell Unix. Biểu mẫu someprogram < somefile báo cho someprogram chạy bằng somefile làm đầu vào của nó. Nếu bạn muốn làm điều gì đó khác biệt liên quan đến biểu tượng <, bạn sẽ cần phải báo nó.

0

< có nghĩa là chương trình sẽ đọc đầu vào tiêu chuẩn (stdin) từ tệp được đặt tên (đầu vào). Vì vậy, chỉ cần đọc từ stdin (sử dụng fgets, fread, v.v ...).

0

Rời khỏi '<'. Bạn muốn đối số dòng lệnh làm điều này:

$ ./program -Dflag Bảy = ixnay FromDinger

Trong ứng dụng của bạn, hãy thử này:

int main(int argc, char **argv) 
{ 
    int i; 
    for(i = 0 ; i < argc ; ++i) 
     printf("Arg %d = %s\n", i, argv[i]); 
    return 0; 
} 

Bạn sẽ nhận thấy rằng đối số đầu tiên là tên của tệp thực thi (tại chỉ mục 0) và đối số thứ hai của bạn (tại chỉ mục 1) sẽ là "-Dflag"

0

Thực ra, đây là một kỹ thuật rất phổ biến được sử dụng trong p các giải đấu rogramming. Các dữ liệu chương trình của bạn cần được lưu trữ trong một tập tin, chúng ta hãy nói data.txt, và sau đó chuyển hướng đến ứng dụng của bạn bằng cách sử dụng "<" trên vỏ, như thế này: ./program < data.txt

Vì vậy, trong mã nguồn của bạn, những gì bạn cần làm là một cái gì đó như thế này:

#include <iostream> 
#include <string> 

using namespace std; 

int main(void) 
{ 
    string tmp; 
    string full_content; 

    while (cin >> tmp) 
     full_content += " "+tmp; 

    cout << full_content << endl; 
} 

.. và bạn sẽ nhận được tất cả dữ liệu từ tệp trên một chuỗi (và cách nhau bằng dấu cách).

Đó là một cách để làm điều đó, tôi hy vọng điều đó sẽ hữu ích. [] 's

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