2015-11-14 58 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