2011-06-19 10 views
0

現在、ICUディクショナリベースのブレークイテレータに新たに追加していくつかのテストを行っています。 テキスト文書で単語の区切りをテストできるコードがありますが、テキスト文書が大きすぎるとエラーになります:bash:./a.out:引数リストが長すぎますヘルプ "コードリストを長すぎます"エラーを修正するエラー

わかりませんコードを編集して引数リストを分割して長すぎると、どのサイズのファイルでもコードを実行することができます。元のコード作成者はかなり忙しいですが、助けてくれる人がいますか?

大切なファイルにはエラーが表示されます(検査するものは必要ありません - 結果が必要です)。

ソーステキストファイルを1行ずつ読み込み、結果を1行ずつ別のテキストファイルに書き出すようにコードを修正することができれば(完了したらすべての行で終わる)、それは完璧です。次のように

コードは次のとおりです。

/* 
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

ああ、そうです。いいえ、シェルが単語の区切りをどのように処理するのかを知ることではありません。結果ファイルの場合だけです。行ごとにテキストを読み取るコードを変更するのに役立つでしょうか? – 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

ありがとうございますFredrik - もう少し詳細を記入できますか?私は失っている...申し訳ありません!古いコードのint main関数をあなたのコードに置き換えますか?私はそれを試みましたが、エラーが発生しました。InsertZWSlarge.cpp:80:5:エラー: 'if'の前にunqualified-idが予期されました InsertZWSlarge.cpp:88:5:error: 'boundary'はタイプに名前を付けません InsertZWSlarge.cpp: 91:5:エラー: 'の間に未修飾のIDが期待されました だから私は間違っていたと思っています... – Nathan

+0

こんにちはフレッドリック!ご協力いただきありがとうございます!申し訳ありませんが、私の経験は限られているので、私はまだそれを動作させることはできません。あなたの更新されたコードは、あなたが以前に書いたものを置き換えますか?おそらくそれはICUとの互換性の問題です...しかし、おそらく私の愚かさ:P私は質問に投稿したコードであなたのコードをインラインで置くことができますか?ありがとう! – Nathan

1

Argument list too longエラーメッセージがbashシェルから送信されていて、コードが実行を開始する前に起きています。

この問題を解決するために修正できる唯一のコードは、bashソースコード(あるいはそれがカーネルに入っているかもしれません)です。そして、あなたはいつも限界に遭遇します。コマンドラインで2048ファイルから10,000に増やすと、10,001ファイルを処理する必要があります.-)

「大きすぎる」引数リストを管理するためのソリューションは数多くあります。

標準化されたソリューションはxargsユーティリティです。

find/-print | xargs echo 

は役立たないが、実際の例です。

詳細はHow to use "xargs" properly when argument list is too longを参照してください。

xargsにも問題があります。ファイル名には空白、改行文字、その他の不愉快なものが含まれる可能性があるためです。

こちらがお役に立てば幸いです。

関連する問題