2011-06-19 66 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也有问题,因为文件名可能包含空格,换行符和其他不友好的东西。

我希望这会有所帮助。