ifstream无法在递归调用中打开

时间:2010-10-20 19:18:04

标签: c++ linux recursion ifstream

我们在尝试解析输入文件时遇到了一个奇怪的问题。我们的想法是这个文件可以包含其他文件,这些文件也必须被解析。我们在一个定义为

的函数中递归地执行此操作

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

编辑:填写更多代码

2 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:0)

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

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

Windows的限制因系统可用内存量以及系统范围内已创建的对象数而异。

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

编辑:

我发现我误解了你的问题,而且你没有递归地打开相同的文件。无论如何,我会留下我的上段。