帮助编辑代码以修复“参数列表太长”错误

时间:2011-06-19 13:24:33

标签: c++ bash icu

我目前正在使用基于ICU字典的break迭代器的新增功能进行一些测试。 我有代码允许我测试文本文档中的断字但是当文本文档太大时它会给出错误: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

2 个答案:

答案 0 :(得分:1)

Argument list too long错误消息来自bash shell,并且在您的代码开始执行之前发生。

你可以修复的唯一代码就是bash源代码(或者它可能在内核中),然后,你总是会遇到限制。如果从命令行上的2048个文件增加到10,000个,那么有一天你需要处理10,001个文件; - )

管理“太大”的参数列表有很多解决方案。

标准化解决方案是xargs实用程序。

 find / -print | xargs echo 

是一个没有帮助但却很有效的例子。

有关详细信息,请参阅How to use "xargs" properly when argument list is too long

即使xargs也有问题,因为文件名可以包含空格,换行符和其他不友好的东西。

我希望这会有所帮助。

答案 1 :(得分:0)

下面的代码读取名称作为命令行上第一个参数的文件内容,并将其放在str::buffer中。然后,不要使用UnicodeString调用函数argv[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;
}