0

我们在尝试解析输入文件时遇到了一个奇怪的问题。这个想法是这个文件可以包含其他文件,这些文件也必须被解析。我们在定义为的函数中递归地执行此操作

int parse_inp(const char* filename)

主文件解析没有问题,但递归调用无法打开它们的文件流。

int parse_inp(const char* filename)
{
    char buffer[BUFFER_MAX+1];
    char* token;
    std::string tok;
    int keywordSection;
    bool end_of_file;
    int cardNum;

    ...

    int i;
    std::string tempop;
    double tempd1, tempd2;
    SetSegmentCard2 tempSetSegmentCard2;
    int offset;

    printf("%s\n", filename);
    std::ifstream inp;
    inp.clear();
    inp.open(filename, std::ios::in);
    if(!inp.good() || !inp.is_open())
    {
        char path1[256];
        getcwd(path1,256);
        printf("CWD: %s\n", path1);
        fflush(NULL);
        printf("Unable to open '%s'\n", filename);
        return 0;
    }
    std::set<std::string> unrecognized;
    std::string line;
    while(inp.good() && !inp.eof())
    {
        getline(inp, line);
        strcpy(buffer, line.c_str());

        if (isComments(buffer)) //skip the comments line
            continue;

        if (buffer[0]=='*') //this is a keyword line
        {
            token = strtok(buffer," \n");
            keywordSection = is_inp_keyw(token);

            if (keywordSection==0)
                unrecognized.insert(token);
            cardNum = 0;
            continue;
        }

        //a data line
        tempop="";
        char* found = NULL;
        char path_buffer[100] = "Dyna3DWriter\\";
        int pos = 0;
        switch(keywordSection)
        {
            case 0: //not recognized
                //end of last keyword, not recognizable word
                break;
            case 1: //KEYWORD
                //"KEYWORD didn't do anything
                break;
            case 2: //TITLE
                break;
            case 3: //INCLUDE
                token = strtok(buffer, "\n");
                inp.clear();
                parse_inp(token);
                break;
            ...
        }
    }
    if(inp.is_open())
    {
        inp.close();
        inp.clear();
    }
}

递归文件永远不会解析。我环顾四周,大多数问题似乎要么是设置了失败位(这就是我们经常调用inp.clear()的原因),要么是我们对当前工作目录做出了错误的假设。

为了测试第二个理论,我们添加了:

if(!inp.good() || !inp.is_open())
{
    char path1[256];
    getcwd(path1,256);
    printf("CWD: %s\n", path1);
    fflush(NULL);
    printf("Unable to open '%s'\n", filename);
    return 0;
}

而且我们的工作目录和文件名都是正确的。fopen(filename, "r")我们在使用--- 调用结果时看到相同的行为perror("fopen")

fopen: no such file or directory

编辑:填写更多代码

4

2 回答 2

2

您确定文件名不包含任何会导致此问题的垃圾或错误字符吗?如果错误是找不到文件,则意味着文件名在某种程度上是错误的。

它可能来自一个错误的声明buffer吗?我们在您的代码中看不到它。

另一种可能性是您strtok在打开文件之前在初始化中再次使用。您必须避免使用strtok这种基于全局存储的递归方法。你应该strtok_r改用。

于 2010-10-20T20:09:04.663 回答
0

如果你的递归函数被调用得很深,你可以很容易地超过操作系统对打开文件数量的限制。

我曾经运行我的 Gentoo Linux,每个进程的文件限制为 250 个,但需要更多文件的程序除外。

Windows 的限制取决于系统可用的内存量以及系统范围内已经创建了多少对象。

做到这一点的聪明方法是拥有两个功能。第一个函数是其他人调用的函数,它进行设置,包括打开文件。第二个函数是递归函数,它只需要一个对 std::ifstream 对象的引用。

编辑:

我看到我误解了您的问题,并且您没有递归地打开同一个文件。无论如何,我会留下我的上述段落。

于 2010-10-20T20:23:03.647 回答