2011-06-19 39 views
0

我目前正在做一些測試,並在ICU基於字典的中斷迭代器中添加了一個新的測試。 我有代碼,允許我在文本文檔上測試分詞,但是當文本文檔太大時,會給出錯誤:bash:./a.out:參數列表太長幫助編輯代碼修復「參數列表太長」錯誤

我不確定如何編輯代碼以在參數列表過長時分解參數列表,以便可以通過代碼運行任何大小的文件。原來的代碼作者很忙,有人願意幫忙嗎?

我試圖消除的正在研究什麼,看是否能幫助印刷,但是我還是對大文件的錯誤(打印什麼是被檢查是沒有必要的 - 我只是需要的結果)。

如果代碼可以被修改,以逐行讀取源文本文件行,並通過線將結果導出行另一個文本文件(結束了,當它完成了所有行),這將是完美的。

的代碼如下:

/* 
Written by George Rhoten to test how word segmentation works. 
Code inspired by the break ICU sample. 

Here is an example to run this code under Cygwin. 

PATH=$PATH:icu-test/source/lib ./a.exe "`cat input.txt`" > output.txt 

Encode input.txt as UTF-8. 
The output text is UTF-8. 
*/ 

#include <stdio.h> 
#include <unicode/brkiter.h> 
#include <unicode/ucnv.h> 

#define ZW_SPACE "\xE2\x80\x8B" 

void printUnicodeString(const UnicodeString &s) { 
    int32_t len = s.length() * U8_MAX_LENGTH + 1; 
    char *charBuf = new char[len]; 
    len = s.extract(0, s.length(), charBuf, len, NULL); 
    charBuf[len] = 0; 
    printf("%s", charBuf); 
    delete charBuf; 
} 

/* Creating and using text boundaries */ 
int main(int argc, char **argv) 
{ 
    ucnv_setDefaultName("UTF-8"); 
    UnicodeString stringToExamine("Aaa bbb ccc. Ddd eee fff."); 
    printf("Examining: "); 
    if (argc > 1) { 
     // Override the default charset. 
     stringToExamine = UnicodeString(argv[1]); 
     if (stringToExamine.charAt(0) == 0xFEFF) { 
      // Remove the BOM 
      stringToExamine = UnicodeString(stringToExamine, 1); 
     } 
    } 
    printUnicodeString(stringToExamine); 
    puts(""); 

    //print each sentence in forward and reverse order 
    UErrorCode status = U_ZERO_ERROR; 
    BreakIterator* boundary = BreakIterator::createWordInstance(NULL, status); 
    if (U_FAILURE(status)) { 
     printf("Failed to create sentence break iterator. status = %s", 
      u_errorName(status)); 
     exit(1); 
    } 

    printf("Result: "); 
    //print each word in order 
    boundary->setText(stringToExamine); 
    int32_t start = boundary->first(); 
    int32_t end = boundary->next(); 
    while (end != BreakIterator::DONE) { 
     if (start != 0) { 
      printf(ZW_SPACE); 
     } 
     printUnicodeString(UnicodeString(stringToExamine, start, end-start)); 
     start = end; 
     end = boundary->next(); 
    } 

    delete boundary; 

    return 0; 
} 

非常感謝! -Nathan

+0

嗯,是的,這是有幫助的。不,它不是看shell如何處理斷詞 - 它只是爲了生成的文件 - 你能幫助改變代碼逐行閱讀文本嗎? – Nathan

+1

我不小心刪除了我的評論:-)要從C++中讀取文件,請參閱http://www.cplusplus.com/doc/tutorial/files/發佈您的代碼,我很樂意幫助您... –

+0

我想知道它到底在哪裏:)需要修改以逐行閱讀的代碼在問題中。我個人不瞭解C++ - 原始代碼是由某人幫助我提交ICU提交的,但他很忙,所以我想我會在其他地方看看。謝謝你的幫助! – Nathan

回答

0

下面的代碼讀取衛生組織名的文件的內容被指定爲在命令行的第一個參數,並將其放置在一個str::buffer。然後,而不是調用功能UnicodeStringargv[1],而是使用該緩衝區。

#include<iostream> 
#include<fstream> 

using namespace std; 

int main(int argc, char **argv) 
{ 
    std::string buffer; 

    if(argc > 1) { 
     std::ifstream t; 
     t.open(argv[1]); 
     std::string line; 
     while(t){ 
      std::getline(t, line); 
      buffer += line + '\n'; 
     } 
    } 
    cout << buffer; 
    return 0; 
} 

更新:

輸入到UnicodeString應該char*。功能GetFileIntoCharPointer這樣做。 請注意,下面僅實現最基本的錯誤檢查!

#include<iostream> 
#include<fstream> 

using namespace std; 

char * GetFileIntoCharPointer(char *pFile, long &lRet) 
{ 
    FILE * fp = fopen(pFile,"rb"); 
    if (fp == NULL) return 0; 

    fseek(fp, 0, SEEK_END); 
    long size = ftell(fp); 
    fseek(fp, 0, SEEK_SET); 

    char *pData = new char[size + 1]; 
    lRet = fread(pData, sizeof(char), size, fp); 

    fclose(fp); 

    return pData; 
} 

int main(int argc, char **argv) 
{ 
    long Len; 
    char * Data = GetFileIntoCharPointer(argv[1], Len); 
    std::cout << Data << std::endl; 

    if (Data != NULL) 
     delete [] Data; 

    return 0; 
} 
+0

謝謝弗雷德裏克 - 你能夠補充一點細節嗎?我很茫然......對不起!用你的代碼替換舊代碼中的int main函數嗎?我嘗試過,但我得到的錯誤:InsertZWSlarge.cpp:80:5:錯誤:期望'if' InsertZWSlarge.cpp:88:5:錯誤:'邊界'未命名類型 InsertZWSlarge.cpp: 91:5:錯誤:期待''while' 之前的非限定標識所以我在想我做錯了... – Nathan

+0

嗨Fredrik!謝謝你的幫助!對不起,我的經驗是如此有限,我仍然無法得到它的工作。你更新的代碼取代你以前寫的對嗎?也許這是與ICU的兼容性問題......但更可能是我的愚蠢:P你能否將你的代碼與我在問題中發佈的代碼內聯?謝謝! – Nathan

1

Argument list too long錯誤消息來自bash shell,並且在您的代碼甚至開始執行之前發生。

您可以修復,以消除此問題的唯一代碼是bash的源代碼(或也許它是在內核中),然後,你總是要碰到的限制。如果從2048個文件增加命令行至10000,然後有一天你需要處理10,001文件;-)

有來管理「過大」參數列表衆多的解決方案。

標準化的解決方案是xargs實用程序。

find/-print | xargs echo 

是一個沒有幫助,但工作的例子。

有關更多信息,請參閱How to use "xargs" properly when argument list is too long

即使xargs也有問題,因爲文件名可能包含空格,換行符和其他不友好的東西。

我希望這會有所幫助。