2009-10-11 31 views
0

我有以下代码,到目前为止,我想检查文件名是否已经在链接列表fileList(或flist)中。根据输出,保存在第一个节点中的字符串在Node* getFileName(Node *&flist)的某处发生了变化。这是怎么发生的?另外,还有什么我正在做的是关于节点和字符串指针的错误或不安全?为什么这个字符串改变了?

输出:

 
in main: file4.txt 
start of process: file4.txt 
file4.txt 
mid of process: file4.txt" 
in contains, fileName in node: file4.txt" 
in contains, target file name: file4.txt 
end of process: file4.txt" 
0 
no recursive call 

代码:

struct Node { 
    string fileName; 
    Node *link; 
}; 


/* 
* 
*/ 
bool contains (Node *&flist, string &name) { 
    Node *tempNode = *&flist; 
    while (tempNode != 0) { 
     cout << "in contains, fileName in node: " << flist->fileName << endl; 
     cout << "in contains, target file name: " << name << endl; 
     if ((tempNode->fileName) == name) { 
      return true; 
     } 
     else { 
      tempNode = tempNode->link; 
     } 
    } 
    return false; 
} 


/* 
* 
*/ 
Node* getLastNode (Node *&flist) { 
    Node *tempNode = *&flist; 
    while (tempNode != 0) { 
     tempNode = tempNode->link; 
    } 
    return tempNode; 
} 


/* 
* 
*/ 
string getFileName(string oneLine) { 
    char doubleQuote; 
    doubleQuote = oneLine[9]; 
    if (doubleQuote == '\"') { 
     string sub = oneLine.substr(10);     //getting the file name 
     string::size_type n = sub.size(); 
     sub = sub.substr(0,n-1); 
     cout << sub << endl; 
     return sub; 
    } 
    return NULL; 
} 

/* 
* 
*/ 
void process(istream &in, ostream &out, Node *&flist) { 
    cout << "start of process: " << flist->fileName << endl; 
    string oneLine;   //temp line holder 
    while (getline(in, oneLine)) { 
     //  cout << oneLine << endl; 
     string::size_type loc = oneLine.find("#include",0); 
     if (loc != string::npos) { 
      //found one line starting with "#include" 
      string name; 
      name = getFileName(oneLine); 
      cout << "mid of process: " << flist->fileName << endl; 
      bool recursive; 
      recursive = contains(flist, name); 
      cout << "end of process: " << flist->fileName << endl; 
      cout << recursive << endl; 
      if (recursive) { 
       //contains recursive include 
       cerr << "recursive include of file " << name << endl; 
       exit(-1); 
      } 
      else { 
       //valid include 
       cout << "no recursive call" << endl; 

      }//else 
     }//if 
    }//while 

}//process 
/* 
* 
*/ 
int main(int argc, char *argv[]) { 
    istream *infile = &cin;       // default value 
    ostream *outfile = &cout;       // default value 
    Node* fileList; 

    switch (argc) { 
    case 3: 
     outfile = new ofstream(argv[2]);   // open the outfile file 
     if (outfile->fail()) { 
      cerr << "Can't open output file " << argv[2] << endl; 
      exit(-1); 
     } 
     // FALL THROUGH to handle input file 
    case 2: 
     infile = new ifstream(argv[1]);   // open the input file 
     if (infile->fail()) { 
      cerr << "Can't open input file " << argv[1] << endl; 
      exit(-1); 
     } 
     else { 
      Node aFile = {argv[1], 0}; 
      fileList = &aFile; 
      cout << "in main: " << fileList->fileName << endl; 
     } 
     // FALL THROUGH 
    case 1:          // use cin and cout 
     break; 
    default:          // too many arguments 
     cerr << "Usage: " << argv[0] << " [ input-file [ output-file ] ]" << endl; 
     exit(-1);         // TERMINATE! 
    } 

    processOneFile (*infile, *outfile, fileList); 

    // do something 
    if (infile != &cin) delete infile;    // close file, do not delete cin! 
    if (outfile != &cout) delete outfile;   // close file, do not delete cout! 
} 
+0

您是否尝试过使用调试器逐步执行代码?它应该比使用'print'语句显示哪个语句更改您的数据更成功。 – 2009-10-11 18:28:04

+0

您能否为我们提供编译此文件所需的文件? – 2009-10-11 18:39:44

+0

我建议也使用std :: set来维护文件名而不是自制的列表。 – dimba 2009-10-11 19:29:53

回答

2

你可以张贴的原代码?你发布的代码甚至没有编译。

错误,我已经注意到,为了:

processOneFile (*infile, *outfile, fileList); 

没有processOneFile()程序。

istream *infile = &cin;       // default value 
ostream *outfile = &cout;       // default value 
Node* fileList; 
case 1:          // use cin and cout 
    break; 
processOneFile (*infile, *outfile, fileList); 

这将调用processOneFile()未初始化的文件列表,当您尝试打印的文件名,这将崩溃。

else { 
      Node aFile = {argv[1], 0}; 
      fileList = &aFile; 
      cout << "in main: " << fileList->fileName << endl; 
    } 

aFile处只在于else范围之内,因此试图用一个指针,它以后将失败。

string getFileName(string oneLine) { 
    /// 
    return NULL; 
} 

您不能std::stringNULL建设 - 这会使程序崩溃。

修复这些错误后,您的代码不会崩溃,我无法重现该错误。

如果您在Linux中构建,请尝试提高警告级别(使用g++ -Wall -Wextra -ansi -pedantic)并通过valgrind运行您的代码来检查内存错误。

+0

此外,没有像“getFileName(Node *&flist)”这样的功能,这是suposedly导致问题。只有一个“getFileName(string oneLine)”,但是这不可能改变其中一个节点中的字符串。 – 2009-10-11 18:43:23

+0

您可以从NULL初始化一个字符串。该字符串将是空的。 – GManNickG 2009-10-11 18:44:37

+0

@GMan:不,从'NULL'初始化'std :: string'是未定义的。在我的系统(和键盘,http://codepad.org/ZldIZHwo)上,它引发了一个异常。 – 2009-10-11 19:09:55

0

好了,代码没有现在看起来它按预期工作:

#include <iostream> 
#include <fstream> 

using namespace::std; 

struct Node 
{ 
    string fileName; 
    Node *link; 
}; 

bool contains (Node *&flist, string &name) 
{ 
    Node *tempNode = *&flist; 
    while (tempNode != 0) 
    { 
     cout << "Searching in \"" << flist->fileName; 
     cout << "\" for \"" << name << "\"" << endl; 
     if (tempNode->fileName == name) 
     { 
      return true; 
     } 
     else 
     { 
      tempNode = tempNode->link; 
     } 
    } 
    return false; 
} 

Node* getLastNode (Node *&flist) 
{ 
    Node *tempNode = *&flist; 
    while (tempNode != 0) 
    { 
     tempNode = tempNode->link; 
    } 
    return tempNode; 
} 

string getFileName(string oneLine) 
{ 
    char doubleQuote; 
    doubleQuote = oneLine[9]; 
    if (doubleQuote == '\"') { 
     string sub = oneLine.substr(10);          //getting the file name 
     string::size_type n = sub.size(); 
     sub = sub.substr(0,n-1); 
     return sub; 
    } 
    return ""; 
} 

void process(istream &in, ostream &out, Node *&flist) 
{ 
    cout << "Start of process: " << flist->fileName << endl << endl; 
    string oneLine;     
    while (1) 
    { 
     cout << "Input include statement: "; 
     getline(in, oneLine); 

     if (oneLine == "STOP") 
      return; 

     string::size_type loc = oneLine.find("#include",0); 
     if (loc != string::npos) 
     { 
      //found one line starting with "#include" 
      string name; 
      name = getFileName(oneLine); 
      if (name == "") 
      { 
       cout << "Couldn't find filename, skipping line..." << endl; 
       continue; 
      } 

      if (contains(flist, name)) 
      { 
       //contains recursive include 
       cerr << "Uh, oh! Recursive include of file " << name << endl; 
       exit(-1); 
      } 
      else 
      { 
       cerr << "No recursive include" << endl; 
      } 

     }//if 

     cout << endl; 
    }//while 
} 

int main(int argc, char *argv[]) 
{ 
    Node* fileList = new Node; 
    istream *infile = &cin;       // default value 
    ostream *outfile = &cout;       // default value 
    fileList->fileName = "Input";      // default value 

    switch (argc) 
    { 
     case 3: 
      outfile = new ofstream(argv[2]);   // open the outfile file 
      if (outfile->fail()) { 
       cerr << "Can't open output file " << argv[2] << endl; 
       exit(-1); 
      } 
      // FALL THROUGH to handle input file 
     case 2: 
      infile = new ifstream(argv[1]);   // open the input file 
      if (infile->fail()) { 
       cerr << "Can't open input file " << argv[1] << endl; 
       exit(-1); 
      } 
      else { 
       fileList->fileName = argv[1]; 
       cout << "in main: " << fileList->fileName << endl; 
      } 
      // FALL THROUGH 
     case 1:          // use cin and cout 
      break; 
     default:          // too many arguments 
      cerr << "Usage: " << argv[0] << " [ input-file [ output-file ] ]" << endl; 
      exit(-1);         // TERMINATE! 
    } 

    process(*infile, *outfile, fileList); 

    // do something 
    if (infile != &cin) delete infile;    // close file, do not delete cin! 
    if (outfile != &cout) delete outfile;   // close file, do not delete cout! 
} 
0

而且,你为什么浪费时间写自己的链表时,标准库已经具备了非常好的一个?

+0

当然,这是一项家庭作业。 – 2009-10-11 19:26:24

相关问题