2009-10-11 50 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

相關問題