2015-11-14 51 views
0

我正在爲作業寫一些代碼。它「主要」是有效的,但我遇到一些非常奇怪的問題。文字顯示在首先不放在那裏的cout流中?

每當我使用cout < <時,其中包含的字符不可能來自程序的當前迭代。

下面,您可以在cout輸出中看到「錯誤:關閉標記:」和「rror:關閉標記:」,但執行此操作的代碼從未得到執行,至少根據VS2015和我的斷點執行。

Debug Output

#include <iostream> 
#include <string> 
#include <fstream> 
using namespace std; 

struct Node 
{ 
    Node *next = NULL; 
    string tag{}; 
    int occurrences = 0; 
}; 

class Stack 
{ 
private: 
    Node *top = NULL; 

public: 
    void Push(string inTag); 
    void Pop(); 
    string Peek(); 
}; 

void output(fstream & stream, string output) 
{ 
    cout << output << endl; 
    stream << output << endl; 
} 

void pause() 
{ 
    cin.ignore(32767, '\n'); 
    char dummy[1]{}; 
    cin.getline(dummy, 1); 
} 

class Tag 
{ 

private: 
    Node *head = NULL; 
    Node *tail = NULL; 
    string tag{}; 
    int occurrences = 0; 

public: 

    // AddTag that doesn't care about occurrences (for empty elements tags) 
    void AddTag(string inTag) 
    { 
     // List empty 
     if (head == NULL) 
     { 
      Node *curr = NULL; 
      curr = new Node; 
      curr->next = NULL; 
      curr->tag = inTag; 
      head = curr; 
      tail = curr; 
      return; 
     } 

     // List populated - inTag becomes new head 
     if (head->tag > inTag) 
     { 
      Node *curr = NULL; 
      curr = new Node; 
      curr->next = head; 
      curr->tag = inTag; 
      head = curr; 
      return; 
     } 

     // List populated - inTag becomes new tail 
     if (tail->tag <= inTag) 
     { 
      Node *curr = NULL; 
      curr = new Node; 
      curr->next = NULL; 
      curr->tag = inTag; 
      tail->next = curr; 
      tail = curr; 
      return; 
     } 

     // List populated - inTag goes somewhere in between 
     if (head->tag < inTag && tail->tag > inTag) 
     { 
      Node *curr = NULL; 
      Node *temp = NULL; 
      temp = new Node; 
      temp->tag = inTag; 

      curr = head; 
      while (curr != NULL && inTag > curr->tag && inTag > curr->next->tag) 
      { 
       curr = curr->next; 
      } 

      temp->next = curr->next; 
      curr->next = temp; 

     } 

    } 

    // Searches through linked list, returns pointer if tag found 
    Node* findTag(string inTag) 
    { 
     if (head == NULL) { return NULL; } // If list is empty we know it's not there 

     Node *curr = NULL; 
     curr = head; 

     while (curr != NULL) 
     { 
      if (curr->tag == inTag) // We found it 
      { 
       return curr; 
      } 
      curr = curr->next; 
     } 

     // We didn't find it 
     return NULL; 

    } 

    // AddTag that takes into account occurrences, for unique HTML tags 
    void AddUniqueTag(string inTag) 
    { 
     // Tag found, update the occurrences for that tag 
     Node *found = NULL; 
     found = findTag(inTag); 
     if (found != NULL) 
     { 
      found->occurrences++; 
      return; 
     } 

     // Tag not found, proceed with creating new node 
     // List empty 
     if (head == NULL) 
     { 
      Node *curr = NULL; 
      curr = new Node; 
      curr->next = NULL; 
      curr->tag = inTag; 
      curr->occurrences = 1; 
      head = curr; 
      tail = curr; 
      return; 
     } 

     // List populated - inTag becomes new head 
     if (head->tag > inTag) 
     { 
      Node *curr = NULL; 
      curr = new Node; 
      curr->next = head; 
      curr->tag = inTag; 
      curr->occurrences = 1; 
      head = curr; 
      return; 
     } 

     // List populated - inTag becomes new tail 
     if (tail->tag <= inTag) 
     { 
      Node *curr = NULL; 
      curr = new Node; 
      curr->next = NULL; 
      curr->tag = inTag; 
      curr->occurrences = 1; 
      tail->next = curr; 
      tail = curr; 
      return; 
     } 

     // List populated - inTag goes somewhere in between 
     if (head->tag < inTag && tail->tag > inTag) 
     { 
      Node *curr = NULL; 
      Node *temp = NULL; 
      temp = new Node; 
      temp->tag = inTag; 
      temp->occurrences = 1; 

      curr = head; 
      while (curr != NULL && inTag > curr->tag && inTag > curr->next->tag) 
      { 
       curr = curr->next; 
      } 

      temp->next = curr->next; 
      curr->next = temp; 

     } 

    } 

    void outputList(fstream & outFile) 
    { 
     Node *curr = NULL; 
     curr = head; 

     while (curr != NULL) 
     { 
      output(outFile, "Node tag: " + curr->tag + " Node occurrences: " + to_string(curr->occurrences) + '\n'); 
      curr = curr->next; 
     } 

    } 

}; 

void Stack::Push(string inTag) 
{ 
    if (top == NULL) 
    { 
     top = new Node; 
     top->next = NULL; 
     top->tag = inTag; 
    } 
    else 
    { 
     Node *temp = new Node; 
     temp->next = top; 
     temp->tag = inTag; 
     top = temp; 
    } 

} 

void Stack::Pop() 
{ 
    //Empty stack 
    if (top == NULL) 
    { 
     cout << "Could not pop: There were no elements on the stack." << endl; 
     return; 
    } 

    //Stack contains multiple elements 
    else if (top->next != NULL) 
    { 
     Node *next = top->next; 
     delete top; 
     top = next; 
    } 

    //Stack contains one element 
    else if (top->next == NULL) 
    { 
     delete top; 
     top = NULL; 
    } 
} 

string Stack::Peek() 
{ 
    //Empty stack 
    if (top == NULL) 
    { 
     return ""; 
    } 
    //Stack contains any number of elements 
    else 
    { 
     return top->tag; 
    } 
} 



int main() 
{ 
    Stack myStack; 
    Tag emptyElementTags; 
    Tag uniqueTags; 

    fstream logFile; 
    logFile.open("log.txt", ios::app); 
    if (!logFile) 
    { 
     cout << "Unrecoverable Error: Log file not accessible." << endl; 
     pause(); 
     return 1; 
    } 

    fstream HTMLOutput; 
    HTMLOutput.open("HTMLOutput.txt", ios::out); 
    if (!HTMLOutput) 
    { 
     output(logFile, "Unrecoverable Error: HTML output file not accessible.\n"); 
     pause(); 
     return 1; 
    } 

    fstream emptyElement; 
    emptyElement.open("EmptyElementTags.dat", ios::in); 
    if (!emptyElement) 
    { 
     output(logFile, "Unrecoverable Error: Empty element file not accessible.\n"); 
     pause(); 
     return 1; 
    } 

    // Check to see if empty element file is empty 
    emptyElement.seekg(0, emptyElement.end); 

    int filePos; // Added 
    filePos = emptyElement.tellg(); 

    if (filePos == 0) 
    { 
     output(logFile, "Unrecoverable Error: Empty element file is empty.\n"); 
     pause(); 
     return 1; 
    } 

    emptyElement.seekg(0, emptyElement.beg); 


    fstream HTMLFile1; 
    HTMLFile1.open("File1.html", ios::in); 
    if (!HTMLFile1) 
    { 
     output(logFile, "Unrecoverable Error: HTML file 1 not accessible.\n"); 
     pause(); 
     return 1; 
    } 

    // Check to see if HTML file 1 is empty 
    HTMLFile1.seekg(0, HTMLFile1.end); 

    filePos = HTMLFile1.tellg(); 

    if (filePos == 0) 
    { 
     output(logFile, "Unrecoverable Error: HTML file 1 is empty.\n"); 
     pause(); 
     return 1; 
    } 

    HTMLFile1.seekg(0, HTMLFile1.beg); 

    fstream HTMLFile2; 
    HTMLFile2.open("File2.html", ios::in); 
    if (!HTMLFile2) 
    { 
     cout << "Unrecoverable Error: HTML file 2 not accessible." << endl; 
     return 1; 
    } 

    HTMLFile2.seekg(0, HTMLFile2.end); 

    filePos = HTMLFile2.tellg(); 

    if (filePos == 0) 
    { 
     output(logFile, "Unrecoverable Error: HTML file 2 is empty.\n"); 
     pause(); 
     return 1; 
    } 

    HTMLFile2.seekg(0, HTMLFile2.beg); 

    string inEmptyElement{ " " }; 
    while (std::getline(emptyElement, inEmptyElement)) 
    { 
     emptyElementTags.AddTag(inEmptyElement); 
    } 

    string readHTML{ " " }; 
    string readTag = ""; 

    int tagLoc = 0; 
    int lineLoc = 0; 

    while (std::getline(HTMLFile1, readHTML)) 
    { 
     lineLoc++; 
     output(HTMLOutput, lineLoc + " " + readHTML); 

     for (int i = 0; i < readHTML.length(); i++) 
     { 
      // We found a tag specifier, start reading text 
      if (readHTML[i] == '<') 
      { 
       tagLoc = i; 
       bool closeTag = false; 

       i++; // Move to the next character 

       // Check to see if it's a close tag. 
       if (readHTML[i] == '/') 
       { 
        closeTag = true; 
        i++; 
       } 

       // Read while we are reading letters (no symbols or whitespace 
       while((readHTML[i] >= 65 && readHTML[i] <= 90) || (readHTML[i] >= 97 && readHTML[i] <= 122) || (readHTML[i] >= 48 && readHTML[i] <= 57)) 
       { 
        readTag.push_back(readHTML[i]); 
        i++; 
       } 

       if (readTag.length() > 0) 
       { 

        if (closeTag == true) 
        { 
         // Matching tag was on the stack, so we pop it off. 
         if (myStack.Peek() == readTag) 
         { 
          myStack.Pop(); 

         } 
         else 
         { 

          output(logFile, "Error: Close tag: "); 
          output(logFile, "</" + readTag + ">"); 
          output(logFile, " did not match what was on the stack. Skipping.\n"); 
          output(logFile, "Line: " + to_string(lineLoc) + " Character: " + to_string(tagLoc + 1) + "\n"); 

          cout << "Error: Close tag: </" << readTag << "> did not match what was on the stack. Skipping." << endl; 
          cout << "Line: " << to_string(lineLoc) << " Character: " << to_string(tagLoc + 1) << endl; 
         } 

         closeTag = false; 
        } 

        else 
        { 
         uniqueTags.AddUniqueTag(readTag);    
         myStack.Push(readTag); 
        } 



       } 
       else 
       { 
        output(logFile, "Error: Tag at line " + to_string(lineLoc) + " character " + to_string(tagLoc + 1) + "contained no letters.\n"); 
       } 

      } 

      readTag.clear();   

     } 


    } 

    //emptyElementTags.outputList(); 
    uniqueTags.outputList(HTMLOutput); 

    cout << "We're done." << endl; 
    pause(); 
    return 0; 

} 

什麼原因可能是任何想法?

+2

通常,當發生這種情況時,這是因爲您運行的代碼不是您認爲正在運行的代碼,例如您的代碼中存在編譯錯誤,而您正在運行舊版本... –

+0

謝謝,同意。我也這麼認爲,這就是爲什麼我重建代碼並重新啓動VS2015。不幸的是沒有骰子。 :( – Irongrave

+2

這是一個*很多*的代碼,請儘量減少它,你也可以很好地找到答案。 – Quentin

回答

0

我想通了。

在這一行:

output(HTMLOutput, lineLoc + " " + readHTML); 

lineLoc是一個整數。我需要一個to_string:

output(HTMLOutput, to_string(lineLoc) + " " + readHTML); 

我想,當你嘗試使用操作符+一個整數,一個const char和一個字符串奇怪的事情都可能發生!

+1

不是奇怪的,只是普通的C風格指針算術。當你走出字符串並拿起時,它確實變得有點奇怪[和undefined]在你添加的字符串後面有一個「隨機」字符串,但是「Hello,World」+ 7'是「W」 orld「'和完全有效的C或C++代碼,'7 +」Hello,World「'完全一樣。 –

+0

你說得對。有趣的是,我不知道你可以做到這一點。去研究指針算術。 – Irongrave