在测试我的getStartNode()和getEndNode()函数时,我一直收到分段错误错误。当我使用带有字符串文字作为参数的search()函数分配startNode / endNode时它工作正常,但是当我使用由于某种原因分配了name本身的字符串时,它没有给我一个分段错误。 问题行出现在generateGraph(字符串文件)函数中。
我的问题是,为什么它可以使用字符串文字,而不是使用与文字本身分配相同值的字符串?
编译:g ++ -std = c ++ 11 main.cpp Node.h Node.cpp Graph.h Graph.cpp
运行:./ a.out SampleGraph.txt
的main.cpp
#include <iostream>
#include <fstream>
#include <string>
//#include "Banner.h"
//#include "Player.h"
#include "Graph.h"
#include "Node.h"
using namespace std;
int main(int argc, char *argv[])
{
string file = argv[1];
cout << file << endl;
Graph maze;
maze.generateGraph(file);
// Welcome banner for start of game
//Banner welcome("Welcome to the Snakes and Ladders Maze Game");
//cout << welcome.getBanner() << endl;
// Testing
cout << maze.getNumberOfNodes() << endl;
cout << maze.getNodeList()[47].getNodeName() << endl;
cout << maze.getNodeList()[4].getAttachedNode(0)->getNodeName() << endl;
cout << maze.getStartNode()->getNodeName() << endl;
cout << maze.getEndNode()->getNodeName() << endl;
return 0;
}
Node.h
#ifndef NODE_H
#define NODE_H
#include <string>
class Node
{
public:
Node();
Node(std::string newname);
void setNodeName(std::string newname);
std::string getNodeName();
void attachNewNode(Node *newNode, int direction);
Node *getAttachedNode(int direction);
void attachSnakeLadderNode(Node *newNode);
Node *getSnakeLadderNode();
private:
std::string name; // Name of Node
Node *attachedNodes[4];
Node *snakeOrLadderNodes;
};
#endif // NODE_H
Node.cpp
#include "Node.h"
using namespace std;
//enum Direction {N, E, S, W};
// Constructors
Node::Node()
{
}
Node::Node(string newname)
{
name = newname;
}
// Function: setNodeName
// Inputs: string newname
// Outputs: void
// Description: Assigns name of Node to newname
void Node::setNodeName(string newname)
{
name = newname;
}
// Function: getNodeName
// Inputs: None
// Outputs: string
// Description: Returns the Nodes name.
string Node::getNodeName()
{
return name;
}
// Function: attachNewNode
// Inputs: Node *newNode, int direction
// Outputs: void
// Description: Attaches a new node with a specific direction.
void Node::attachNewNode(Node *newNode, int direction)
{
attachedNodes[direction] = newNode;
}
// Function: *getAttachedNode
// Inputs: int direction
// Outputs: Node
// Description: Returns the Node located at specified direction.
Node *Node::getAttachedNode(int direction)
{
return attachedNodes[direction];
}
// Function: attachSnakeLadderNode
// Inputs: Node *newNode
// Outputs: void
// Description: Attaches snake/ladder Node
void Node::attachSnakeLadderNode(Node *newNode)
{
snakeOrLadderNodes = newNode;
}
// Function: *getSnakeLadderNode
// Inputs: None
// Outputs: Node
// Description: Returns snake/ladder Node.
Node *Node::getSnakeLadderNode()
{
return snakeOrLadderNodes;
}
Graph.h
#ifndef GRAPH_H
#define GRAPH_H
#include <fstream>
#include <sstream>
#include <vector>
#include "Node.h"
class Graph
{
public:
Graph();
void setNumberOfNodes(int num);
int getNumberOfNodes();
void setNodeList(int num);
Node *getNodeList();
Node *search(std::string target);
void setStartNode(Node *newNode);
Node *getStartNode();
void setEndNode(Node *newNode);
Node *getEndNode();
void generateGraph(std::string file);
private:
int numOfNodes;
Node *nodeList;
Node *startNode;
Node *endNode;
};
#endif // GRAPH_H
Graph.cpp
#include "Graph.h"
#include <iostream>
#include <cstdlib>
using namespace std;
// Constructor
Graph::Graph()
{
}
// Function: setNumberofNodes
// Inputs: int num
// Outputs: void
// Description: Sets the number of Nodes
void Graph::setNumberOfNodes(int num)
{
numOfNodes = num;
}
// Function: getNumberOfNodes
// Inputs: None
// Outputs: int
// Description: Return number of Nodes.
int Graph::getNumberOfNodes()
{
return numOfNodes;
}
// Function: setNodeList
// Inputs: int numOfNodes
// Outputs: void
// Description: Sets the Node list with size of numOfNodes.
void Graph::setNodeList(int num)
{
nodeList = new Node[num];
}
// Function: getNodeList
// Inputs: None
// Outputs: nodeList
// Description: Returns pointer to array of nodes
Node *Graph::getNodeList()
{
return nodeList;
}
// Function: search
// Inputs: string name of node target
// Outputs: Pointer to found node
// Description: Returns pointer of the targeted node.
Node *Graph::search(string target)
{
for (int i = 0; i < numOfNodes; i++)
{
if (nodeList[i].getNodeName() == target)
{
return &nodeList[i];
}
}
}
void Graph::setStartNode(Node *newNode)
{
startNode = newNode;
}
// Function: getStartNode
// Inputs: None
// Outputs: Node *startNode
// Description: Returns pointer to starting node.
Node *Graph::getStartNode()
{
return startNode;
}
void Graph::setEndNode(Node *newNode)
{
endNode = newNode;
}
// Function: getEndNode
// Inputs: None
// Outputs: Node *endNode
// Description: Returns pointer to destination node.
Node *Graph::getEndNode()
{
return endNode;
}
// Function: generateGraph
// Inputs:
// Outputs:
// Description:
void Graph::generateGraph(string inFile)
{
ifstream fin;
fin.open(inFile);
if (!fin.fail())
{
vector<string> rows;
string row;
// First Line (Number of Nodes)
string numberOfNodes;
getline(fin, numberOfNodes);
setNumberOfNodes(stoi(numberOfNodes));
setNodeList(numOfNodes);
// Second Line (Start Node)
string startNodeName;
getline(fin, startNodeName);
// Third Line (Destination Node)
string endNodeName;
getline(fin, endNodeName);
// Fourth-Last Lines (Graph)
while (!fin.eof()) // Scans remaining rows of file and adds each line to a vector<string>
{
getline(fin, row);
rows.push_back(row);
}
fin.close();
// Reads the first column, creates Node objects with names and adds it to the node list
for (int i = 0; i < numOfNodes; i++)
{
string nodeName;
istringstream iss(rows[i]);
iss >> nodeName;
nodeList[i] = Node(nodeName);
} // end loop
// Assign start/end nodes
cout << "Start node: " << startNodeName << endl;
setStartNode(search(startNodeName)); // Problem, should be A1
// setStartNode(search("A1")); // Works, but start node can change.
setEndNode(search(endNodeName)); // Problem, should be H6
// setEndNode(search("H6")); //Works, but end node can change.
// Reads lines stored in vector<string> and links each node
string info;
string north, east, south, west, snake_ladder;
for (int i = 0; i < numOfNodes; i++)
{
info = rows[i].substr(rows[i].find(" ") + 1, string::npos);
istringstream iss(info);
iss >> north >> east >> south >> west >> snake_ladder;
// Link North Node
if (north == "*")
{
nodeList[i].attachNewNode(NULL, 0);
}
else
{
nodeList[i].attachNewNode(search(north), 0);
}
// Link East Node
if (east == "*")
{
nodeList[i].attachNewNode(NULL, 1);
}
else
{
nodeList[i].attachNewNode(search(east), 1);
}
// Link South Node
if (south == "*")
{
nodeList[i].attachNewNode(NULL, 2);
}
else
{
nodeList[i].attachNewNode(search(south), 2);
}
// Link West Node
if (west == "*")
{
nodeList[i].attachNewNode(NULL, 3);
}
else
{
nodeList[i].attachNewNode(search(west), 3);
}
// Link Snake/Ladder Node
if (snake_ladder == "*")
{
nodeList[i].attachSnakeLadderNode(NULL);
}
else
{
nodeList[i].attachSnakeLadderNode(search(snake_ladder));
}
} // end loop
}
else
{
cerr << "\n\t*** ERROR: File failed to open, program terminating! ***\n" << endl;
exit(0);
}
}
SampleGraph.txt
48
A1
H6
A1 * B1 * * *
B1 B2 * * * *
C1 C2 D1 * * *
D1 * * * * G3
E1 E2 F1 * * B1
F1 * * * E1 *
G1 G2 H1 * * *
H1 * * * G1 G5
A2 A3 B2 * * *
B2 * C2 B1 A2 *
C2 C3 * C1 B2 *
D2 D3 E2 * * *
E2 * * E1 D2 *
F2 F3 G2 * * *
G2 * H2 G1 F2 *
H2 * * * G2 E4
A3 * * A2 * D3
B3 B4 C3 * * *
C3 * D3 C2 B3 *
D3 D4 * D2 C3 *
E3 * F3 * * *
F3 F4 * F2 E3 *
G3 G4 H3 * * *
H3 H4 * * G3 *
A4 * B4 * * *
B4 B5 * B3 A4 *
C4 * D4 * * F2
D4 D5 E4 D3 C4 *
E4 * F4 * D4 *
F4 * G4 F3 E4 *
G4 G5 * G3 F4 *
H4 * * H3 * *
A5 A6 B5 * * *
B5 * C5 B4 A5 *
C5 * * * B5 B2
D5 D6 E5 D4 * *
E5 * F5 * D5 *
F5 F6 * * E5 *
G5 * H5 G4 * *
H5 H6 * * G5 *
A6 * B6 A5 * *
B6 * C6 * A6 E5
C6 * * * B6 *
D6 * * D5 * C3
E6 * F6 * * *
F6 * G6 F5 E6 *
G6 * * * F6 F4
H6 * * H5 * *
答案 0 :(得分:1)
使用getline
获取单个字时,您需要删除尾随换行符。
您实际上没有按预期阅读"A1"
,而是"A1\n"
。