2012-05-01 68 views
24

Tôi đang cố gắng lấy một tập hợp chín tệp * .c (và chín tệp * .h có liên quan) để biên dịch trong Windows.getopt.h: Biên dịch mã C-C trong Windows

Mã ban đầu được thiết kế trong Linux để lấy đối số dòng lệnh bằng cách sử dụng thư viện GNU-Linux/C chuẩn "getopt.h". Và thư viện đó không áp dụng để xây dựng mã C trong Windows.

Tôi muốn bỏ qua mã của mình ngay bây giờ và đặt câu hỏi sau. Đối với những người bạn quen thuộc với thư viện C "getopt.h": liệu có thể xây dựng và chạy mã của tôi trong Windows nếu nó phụ thuộc vào các đối số dòng lệnh kiểu POSIX? Hoặc tôi sẽ phải viết lại mã để làm việc cho Windows, chuyển các tệp đầu vào khác nhau (và bỏ qua phụ thuộc "getopt.h")?

+2

nếu hỗ trợ MSVC không phải là một yêu cầu khó khăn, luôn có MinGW: Tôi m khá hài lòng với các gói biên dịch chéo MinGW đi kèm với Cygwin ... – Christoph

+2

'getopt.h' ghi lại API được cung cấp bởi các phương thức từ' getopt.c'. Kéo nó từ đâu đó, biên dịch nó và liên kết kết quả với ứng dụng của bạn và hoàn thành của bạn. – alk

+1

Chỉ là một nit liên quan đến bình luận của alk, nó có thể được thực hiện, về mặt kỹ thuật, nhưng tính pháp lý phụ thuộc hoàn toàn vào khả năng tương thích của (các) giấy phép từ các nguồn getopt (nếu có) và của dự án. Một số triển khai getopt nói tên miền công cộng, do đó có khả năng sẽ không có vấn đề gì. – user314159

Trả lời

19

Bạn là chính xác. getopt() là POSIX, không phải Windows, bạn thường sẽ phải viết lại tất cả mã phân tích cú pháp đối số dòng lệnh.

May mắn thay, có một dự án, Xgetopt, có nghĩa là cho các lớp Windows/MFC.

http://www.codeproject.com/Articles/1940/XGetopt-A-Unix-compatible-getopt-for-MFC-and-Win32

Nếu bạn có thể làm việc này trong dự án của bạn, nó sẽ giúp bạn tiết kiệm một chút công bằng của mã hóa và ngăn chặn bạn khỏi phải làm lại tất cả các phân tích cú pháp.

Ngoài ra, ứng dụng này còn có một ứng dụng demo hỗ trợ giao diện đẹp mà bạn sẽ thấy hữu ích.

Chúc may mắn!

+0

Tôi sẽ thử ngay bây giờ. Nhưng tôi không thể nói từ liên kết mà bạn đã hiển thị: API cho thư viện này có giống với API getopt cũ không? – theJollySin

+0

Bạn có thể đặt tên bất kỳ lý do nào để viết lại nhưng thực hiện phân tích cú pháp không? – alk

+0

Mã bạn cần vào cổng là ngày khi nào? @theJollySin – alk

1

Từ những gì tôi nhớ về getopt.h, tất cả nó làm là cung cấp một phân tích cú pháp tiện dụng cho argv chế biến từ hàm main của bạn:

int main(int argc, char * argv[]) 
{ 
} 

chương trình giao diện điều khiển Windows vẫn có một phương pháp chính, vì vậy bạn có thể chỉ đơn giản lặp qua của bạn argv mảng và phân tích các thông số chính mình. ví dụ.

for (int i = 1; i < argc; i++) 
{ 
    if (!strcmp(argv[i], "-f")) 
    filename = argv[++i]; 
} 
+0

Cảm ơn! Tôi không chắc liệu điều này có thực tế đối với tôi hay không. Mặc dù tôi hiểu rằng tôi có thể cuộn qua ~ 5000 dòng mã và viết lại các bit này, đây là mã mà chúng tôi đang nhận được từ các nhà phát triển khác. Vì vậy, điều gì sẽ xảy ra sau 2 tháng khi chúng cung cấp cho chúng tôi phiên bản mã mới hơn một chút? Tôi có phải làm lại mã xử lý đối số mỗi khi chúng tôi nhận được bản cập nhật không? Điều đó nghe có vẻ mất thời gian. – theJollySin

+0

Có vẻ như bạn cần hợp tác với các nhà phát triển khác và đồng ý với một hệ thống chuyển đổi đối số di động. Giải pháp được cung cấp bởi @theJollySin cũng có thể là câu trả lời, nhưng dù sao cũng không khó để viết một trình phân tích đối số di động. – Benj

+2

Trong thời gian API 'getopt' trông yên tĩnh ổn định với tôi. @theJollySin – alk

5

tôi đã biên dịch mã getopt dưới cửa sổ.

Tôi đã làm điều này vì tôi muốn explicilty sử dụng chức năng phân tích cú pháp dòng lệnh của nó trong ứng dụng cửa sổ (dòng lệnh).

Tôi đã thực hiện thành công việc này bằng cách sử dụng VC2010.

Theo như tôi nhớ, tôi không gặp phải vấn đề quan trọng nào.

getopt.cgetoptl.c

+2

Bản chỉnh sửa được đề xuất đã thêm câu * "Xin lưu ý rằng mã cụ thể này được GPLv3 bao trả chứ không phải bởi LGPL." * Cho câu trả lời này. Tôi đã quay lại và bao gồm nhận xét ở đây. –

+0

Er, bao gồm 'getopt.in.h'? –

+0

@VictorSergienko: Chắc chắn một số mã trong 'getopt.in.h' là cần thiết để biên dịch các nguồn' getopt'. Dù sao, câu trả lời của tôi không có nghĩa là phải hiểu cách thức biên dịch các tệp được liên kết là có thể mà không có bất kỳ sửa đổi nhỏ nào. Chỉ cần cho ăn "như là" để VC10 sẽ không hoạt động. – alk

3

Có một khả năng để sử dụng mã từ MinGW runtime (bởi Todd C. Miller):

http://sourceforge.net/apps/trac/mingw-w64/browser/trunk/mingw-w64-crt/misc

Tôi đã tạo ra một thư viện nhỏ với những tập tin này và CMake kịch bản (có thể tạo dự án VS):

https://github.com/alex85k/wingetopt

+0

Dường như thư viện của bạn sẽ thực sự hữu ích. Tôi chỉ muốn nói. Nhưng tôi đã thấy nhận xét của Dogbert về Xgetopt trước tiên và điều đó đã làm được điều đó. Cảm ơn, mặc dù! – theJollySin

32

getopt() thực sự là một chức năng thực sự đơn giản.Tôi đã thực hiện một github gist cho nó, mã from here dưới quá

#include <string.h> 
#include <stdio.h> 

int  opterr = 1,    /* if error message should be printed */ 
    optind = 1,    /* index into parent argv vector */ 
    optopt,     /* character checked for validity */ 
    optreset;    /* reset getopt */ 
char *optarg;    /* argument associated with option */ 

#define BADCH (int)'?' 
#define BADARG (int)':' 
#define EMSG "" 

/* 
* getopt -- 
*  Parse argc/argv argument vector. 
*/ 
int 
    getopt(int nargc, char * const nargv[], const char *ostr) 
{ 
    static char *place = EMSG;    /* option letter processing */ 
    const char *oli;      /* option letter list index */ 

    if (optreset || !*place) {    /* update scanning pointer */ 
    optreset = 0; 
    if (optind >= nargc || *(place = nargv[optind]) != '-') { 
     place = EMSG; 
     return (-1); 
    } 
    if (place[1] && *++place == '-') {  /* found "--" */ 
     ++optind; 
     place = EMSG; 
     return (-1); 
    } 
    }          /* option letter okay? */ 
    if ((optopt = (int)*place++) == (int)':' || 
    !(oli = strchr(ostr, optopt))) { 
     /* 
     * if the user didn't specify '-' as an option, 
     * assume it means -1. 
     */ 
     if (optopt == (int)'-') 
     return (-1); 
     if (!*place) 
     ++optind; 
     if (opterr && *ostr != ':') 
     (void)printf("illegal option -- %c\n", optopt); 
     return (BADCH); 
    } 
    if (*++oli != ':') {     /* don't need argument */ 
    optarg = NULL; 
    if (!*place) 
     ++optind; 
    } 
    else {         /* need an argument */ 
    if (*place)      /* no white space */ 
     optarg = place; 
    else if (nargc <= ++optind) { /* no arg */ 
     place = EMSG; 
     if (*ostr == ':') 
     return (BADARG); 
     if (opterr) 
     (void)printf("option requires an argument -- %c\n", optopt); 
     return (BADCH); 
    } 
    else       /* white space */ 
     optarg = nargv[optind]; 
    place = EMSG; 
    ++optind; 
    } 
    return (optopt);      /* dump back option letter */ 
} 
+2

Tôi có điều này bao gồm trong dự án của tôi, tuy nhiên khi tôi cố gắng sử dụng optarg nó nói rằng nó không được khai báo trong Windows. Giá trị trả về của getopt luôn là lựa chọn. Tôi có thể sử dụng optarg như thế nào? – eleijonmarck

+2

Tệp tiêu đề bị thiếu 'extern char * optarg;' và 'extern int optind, opterr, optopt;' – cubrr

1

Bạn có thể thử nhìn vào lém lỉnh-2.0 như một sự thay thế. Nó sẽ là một chút lớn cho chỉ cần một phân tích cú pháp tùy chọn. Phía lên sẽ có quyền truy cập vào tất cả các đồ chơi tuyệt vời khác trong glib.

Thành thật mà nói, tôi đã không cố gắng làm việc này (tôi chủ yếu dùng Linux), vì vậy YMMV.

Bắt trơn để làm việc trong các cửa sổ: HowTo

Oh, bạn có thể khám phá bằng mingw cho việc xây dựng môi trường, và visual studio cho IDE của bạn.

Glib cho Win32: HowTo

Anywho, hy vọng điều này sẽ giúp.

1

nếu bạn chỉ muốn getopt được sử dụng trong hình ảnh C++ mà không có sự phụ thuộc khác, tôi có cổng getopt.c từ gnu libc 2.12 mới nhất, với tất cả các tính năng mới. Sự khác biệt duy nhất là bạn phải sử dụng TCHAR thay vì char, nhưng điều này rất phổ biến trong các cửa sổ.

chỉ cần tải xuống nguồn, tạo, sao chép libgetopt.lib và getopt.h getopt_int.h vào dự án của bạn.

bạn cũng có thể sử dụng CMakeList.txt trong thư mục gốc.

download the source from github

0

Các getopt.h tồn tại trong git, tôi có tải về nó và nó làm việc cho tôi:

https://gist.github.com/ashelly/7776712

+0

Vâng, việc tìm kiếm getopt.h không phải là vấn đề của tôi. Tôi đã lo lắng hơn về Windows getopt.h hoạt động trong môi trường Linux. Tốt để biết mặc dù. – theJollySin

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