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

发布于 2024-11-15 22:07:29 字数 2382 浏览 4 评论 0原文

我目前正在对基于 ICU 字典的中断迭代器的新添加进行一些测试。 我有代码允许我在文本文档上测试断字,但是当文本文档太大时,会出现错误: bash: ./a.out: Argument list too long

我不知道如何编辑代码当参数列表太长时将其分解,以便任何大小的文件都可以通过代码运行。原代码作者很忙,请问有人愿意帮忙吗?

我尝试删除正在检查的内容的打印,看看是否有帮助,但我仍然在大文件上遇到错误(不需要打印正在检查的内容 - 我只需要结果)。

如果可以修改代码以逐行读取源文本文件并将结果逐行导出到另一个文本文件(完成后得到所有行),那就完美了。

代码如下:

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

非常感谢! -内森

I am currently doing some testing with a new addition to the ICU dictionary-based break iterator.
I have code that allows me to test the word-breaking on a text document but when the text document is too large it gives the error: bash: ./a.out: Argument list too long

I am not sure how to edit the code to break-up the argument list when it gets too long so that a file of any size can be run through the code. The original code author is quite busy, would someone be willing to help out?

I tried removing the printing of what is being examined to see if that would help, but I still get the error on large files (printing what is being examined isn't necessary - I just need the result).

If the code could be modified to read the source text file line by line and export the results line by line to another text file (ending up with all the lines when it is done), that would be perfect.

The code is as follows:

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

Thanks so much!
-Nathan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花心好男孩 2024-11-22 22:07:29

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

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

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

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

 find / -print | xargs echo 

是一个无用但有效的示例。

请参阅如何在参数时正确使用“xargs”列表太长,无法获取更多信息。

甚至 xargs 也有问题,因为文件名可能包含空格、换行符和其他不友好的内容。

我希望这有帮助。

The Argument list too long error message is coming from the bash shell and is happening before your code even gets started executing.

The only code you can fix to eliminate this problem is the bash source code (or maybe it is in the kernel) and then, you're always going to run into a limit. If you increase from 2048 files on command line to 10,000, then some day you'll need to process 10,001 files ;-)

There are numerous solutions to managing 'too big' argument lists.

The standardized solution is the xargs utility.

 find / -print | xargs echo 

is a un-helpful, but working example.

See How to use "xargs" properly when argument list is too long for more info.

Even xargs has problems, because file names can contain spaces, new-line chars, and other unfriendly stuff.

I hope this helps.

烟凡古楼 2024-11-22 22:07:29

下面的代码读取文件名作为命令行第一个参数给出的内容,并将其放置在 str::buffer 中。然后,不要使用 argv[1] 调用函数 UnicodeString,而是使用该缓冲区。

#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;
}

The code below reads the content of a file whos name is given as the first parameter on the command-line and places it in a str::buffer. Then, instead of calling the function UnicodeString with argv[1], use that buffer instead.

#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;
}

Update:

Input to UnicodeString should be char*. The function GetFileIntoCharPointer does that.
Note that only the most rudimentary error checking is implemented below!

#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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文