String是我自己的字符串类,Stack是我自己的堆栈类。 我试图将中缀更改为postfix,其值由空格分隔。
下面的函数几乎可以工作,但也返回“分段错误(核心转储)”。
String postfix(String infix){
std::vector<String> vec;
vec = infix.split(' ');
Stack<String> tmp;
String right, left, op;
int i = 0;
while (vec[i] != ';'){
if (vec[i] == ')'){
right = tmp.pop();
op = tmp.pop();
left = tmp.pop();
tmp.push(left + ' ' + right + ' ' + op);
}else{
if (vec[i] != '(' && vec[i] != ' ')
tmp.push(vec[i]);
}
++i;
}
String postfix = tmp.pop();
return postfix;
}
我不明白为什么会这样。任何帮助将不胜感激。
#ifndef STACK_HPP
#define STACK_HPP
template <typename T>
class Node{
public:
T data;
Node<T>* next;
Node() { data().next(0); } ;
Node (const T& x) : data (x), next(0) {};
};
template <typename T>
class Stack{
public:
Stack() : tos(0){};
~Stack();
Stack(const Stack<T>&);
void swap(Stack<T>& rhs);
Stack<T>& operator= (Stack<T> rhs) { swap(rhs); return *this; };
bool isEmpty() const { return tos == 0; };
T pop();
void push(const T&);
private:
Node<T> *tos;
};
///////////////////////////////////////////////////////////////
template <typename T>
Stack<T>::~Stack(){
while(tos != 0){
Node<T> *tmp = tos;
tos = tos -> next;
delete tmp;
}
}
template <typename T>
void Stack<T>::swap(Stack<T>& rhs){
Node<T> *tmp = tos;
tos = rhs.tos;
rhs.tos = tmp;
}
template <typename T>
Stack<T>::Stack(const Stack<T>& actual){
Node<T> *tmp = actual.tos, *bottom = 0;
tos = 0;
while (tmp != 0){
if(tos == 0){
tos = new Node<T>(tmp -> data);
bottom = tos;
}else{
bottom -> next = new Node<T>(tmp -> data);
bottom = bottom -> next;
}
tmp = tmp -> next;
}
}
template<typename T>
T Stack<T>::pop(){
T result = tos -> data;
Node<T> *tmp = tos;
tos = tos -> next;
delete tmp;
return result;
}
template <typename T>
void Stack<T>::push(const T& x){
Node<T> *tmp = new Node<T> (x);
tmp -> next = tos;
tos = tmp;
}
#endif
//bruce pucci
//string
//cs23001
#include <iostream>
#include <cassert>
#include <vector>
#include <fstream>
#include "string.hpp"
///////////////////////////////string class friend functions////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////I/O/////////////////////////////////////////////
std::ostream& operator<<(std::ostream& out, const String& print){//std::cout operator
int i = 0;
while (print.arr[i] > 0){
out << print.arr[i];
++i;
}
return out;
}
std::ifstream& operator>>(std::ifstream& in, String& rhs){//ifstream operator.
char tmp[stringSize];//grabs word by word (chars serperated by whitespace).
in >> tmp;
rhs = String(tmp);
return in;
}
////////////////////////////////string class public functions///////////////////////
////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////constructors///////////////////////////////////////
String::String(){//default constructor. default size
arr = new char[stringSize];
cap = stringSize;
arr[0] = 0;
}
String::String(const char a){//char constructor. default size
arr = new char[stringSize];
cap = stringSize;
arr[0] = a;
arr[1] = 0;
}
String::String(const char a[]){//char array constructor. default size
arr = new char[stringSize];
cap = stringSize;
int i = 0;
while (a[i] > 0){
arr[i] = a[i];
++i;
}
arr[i] = 0;
}
String::String(const int initSize, const char a[]){//char array constructor. size passed as a parameter
arr = new char[initSize];
cap = initSize;
int i = 0;
while (a[i] > 0){
arr[i] = a[i];
++i;
}
arr[i] = 0;
}
String::String(int initSize){//like default constructor. size passed as parameter
arr = new char[initSize];
cap = initSize;
}
//////////////////////////////////dynamic stuff/////////////////////////////////////////////////
String::String(const String& rhs){//big three. copy constructor
arr = new char[rhs.cap];
cap = rhs.cap;
for (int i = 0; i < cap; ++i)
arr[i] = rhs.arr[i];
}
String::~String(){//big three. destuctor.
delete [] arr;
}
String& String::operator=(String rhs){//big three. assignment operator.
swap(rhs);
return *this;
}
String String::swap(String& rhs){//swap the pointers on 2 char arrays.
int tmpCap = rhs.cap;
rhs.cap = cap;
cap = tmpCap;
char* tmp = rhs.arr;
rhs.arr = arr;
arr = tmp;
return *this;
}
///////////////////////////////////functions////////////////////////////////////////////////////////////////
void String::reallocate(int a){//changes the size of a dynamic String. size passed as parameter.
String tmp;
tmp.cap = a;
tmp.arr = new char[a];//allocate space of size passed.
int i = 0;
while (arr[i] != 0){//copy elements to newly allocated tmp array
tmp.arr[i] = arr[i];
++i;
}
tmp.arr[i] = 0;
swap(tmp);//swap pointers of tmp and passed array
}
std::vector<String> String::split(char splitter) const{//splits a String into a vecotr of
std::vector<String> vecOfStrings;//Strings besed on the delimited passed
int start = 0, end = 0;//returns that vector
bool doIt = false;
for (int i = 0; i < cap; ++i){//look if the delimiter exists
if (arr[i] == ' '){
doIt = true;
break;
}
}
if (doIt){//if the delimiter exists in the string start looping
for (int i = 0; i < cap; ++i){
if (arr[i] == splitter){//when each occurance of the delimiter is found create a
end = i;//node of String in the vector with the chars since the previous node
vecOfStrings.push_back(substr(start, end - 1));
start = (end + 1);
}
if (i == (cap - 1)){//do this until the no more delimiters are found
end = i;
vecOfStrings.push_back(substr(start, end));
}
}
}
return vecOfStrings;
}
int String::length() const{//returns the length of the String before the terminating char.
int counter = 0;
while (arr[counter] != 0)
++counter;
return counter;
}
int String::capacity() const{//accessor to capacity.
return cap;
}
String String::substr(int start, int end) const{//returns a subset string of string passed.
if ((start < 0) || (end < 0))//parameters are starting and ending points of the substring
return String();
String result;
int returnIndex = start;
for (int i = start; i <= end; ++i)
result[i - start] = arr[returnIndex++];
result[end - start + 1] = 0;
return result;
}
int String::findChar(const char target) const{//returns the position of the first occurance of the char
for (int i = 0; i < length(); ++i)//being searched for. returns -1 if the char is not found.
if (arr[i] == target)
return i;
std::cout << "The char was not found." << std::endl;
return -1;
}
int String::findStr(const char target[]) const{//searches for a substring in the string. returns the
String targetString(target);//position of the first char in the substring
return findStr(targetString);//uses the String version of findStr. look there for more info.
}
int String::findStr(const String& target) const{//searches for a substring in the string. returns the
int targetLength = target.length();//position of the first char in the substring
String candidate;//candidate is the string that
int candStart = 0, candEnd = candStart + (targetLength - 1), i = 0;//will be compared to other strings
//of the same length
while (i < (stringSize - targetLength)){//go through char by char and compare candidate to
candidate = substr(candStart++, candEnd++);//strings of the same length within the full string.
if (candidate == target)//ex String = "Hello World." looking for "llo"
return i;//"Hel" == "llo" no "Hel" == "ell" no "llo == "llo" yes.
i++;//return 2.
}
std::cout << "The string was not found." << std::endl;
return -1;//if not found at all return -1
}
int String::stringToInt(){
int result = 0, intTmp;
char charTmp;
for (int i = 0; i < length(); ++i){
charTmp = arr[i];
switch (charTmp){
case '0' : intTmp = 0; break;
case '1' : intTmp = 1; break;
case '2' : intTmp = 2; break;
case '3' : intTmp = 3; break;
case '4' : intTmp = 4; break;
case '5' : intTmp = 5; break;
case '6' : intTmp = 6; break;
case '7' : intTmp = 7; break;
case '8' : intTmp = 8; break;
case '9' : intTmp = 9; break;
case '-' : intTmp = 0; break;
}
if (result > 0)
result = result * 10;
result = result + intTmp;
}
return result;
}
/////////////////////////////////////////////operators////////////////////////////////////////////////////////////////////
char String::operator[](int i) const{//subscript operator. returns char whated in char array. const version.
return arr[i];//acts as an accessor to chars
}
char& String::operator[](int i){//subscript operator. returns char whated in char array. non const version.
return arr[i];//acts as an accessor to chars
}
String String::operator+(const String& rhs) const{//concatenate
String result(arr);
int start = length(), rhsIndex = 0;
while (rhs.arr[rhsIndex] != 0){
result.arr[start] = rhs.arr[rhsIndex];
start++;
rhsIndex++;
}
result.arr[start] = 0;
return result;
}
bool String::operator==(const String& rhs) const{
if (length() != rhs.length())
return false;
for (int i = 0; i < length(); ++i)
if (arr[i] != rhs.arr[i])
return false;
return true;
}
bool String::operator!=(const String& rhs) const{
if (*this == rhs)
return false;
return true;
}
bool String::operator<(const String& rhs) const{
int i = 0;
while (arr[i] != 0 && rhs.arr[i] != 0){
if ((arr[i] - rhs.arr[i]) < 0)
return true;
else if ((arr[i] - rhs.arr[i]) > 0)
return false;
i++;
}
if (length() < rhs.length())
return true;
return false;
}
bool String::operator>(const String& rhs) const{
if (*this == rhs)
return false;
if (*this < rhs)
return false;
return true;
}
bool String::operator<=(const String& rhs) const{
if (*this == rhs)
return true;
if (*this < rhs)
return true;
return false;
}
bool String::operator>=(const String& rhs) const{
if (*this == rhs)
return true;
if (*this < rhs)
return false;
return true;
}
//////////////////////////////free functions////////////////////////////////
////////////////////////////////////////////////////////////////////////////
///////////////they use the public functions of the String class////////////
String operator+(const char lhs[], const String& rhs){
String lhsString(lhs);
String result = lhsString + rhs;
return result;
}
String operator+(const char lhs, const String& rhs){
String lhsString(lhs);
String result = lhsString + rhs;
return result;
}
bool operator==(const char lhs[], const String& rhs){
String lhsString(lhs);
return lhsString == rhs;
}
bool operator==(const char lhs, const String& rhs){
String lhsString(lhs);
return lhsString == rhs;
}
bool operator!=(const char lhs[], const String& rhs){
String lhsString(lhs);
return lhsString != rhs;
}
bool operator!=(const char lhs, const String& rhs){
String lhsString(lhs);
return lhsString != rhs;
}
bool operator<(const char lhs[], const String& rhs){
String lhsString(lhs);
return lhsString < rhs;
}
bool operator<(const char lhs, const String& rhs){
String lhsString(lhs);
return lhsString < rhs;
}
bool operator>(const char lhs[], const String& rhs){
String lhsString(lhs);
return lhsString > rhs;
}
bool operator>(const char lhs, const String& rhs){
String lhsString(lhs);
return lhsString > rhs;
}
bool operator<=(const char lhs[], const String& rhs){
String lhsString(lhs);
return lhsString <= rhs;
}
bool operator<=(const char lhs, const String& rhs){
String lhsString(lhs);
return lhsString <= rhs;
}
bool operator>=(const char lhs[], const String& rhs){
String lhsString(lhs);
return lhsString >= rhs;
}
bool operator>=(const char lhs, const String& rhs){
String lhsString(lhs);
return lhsString >= rhs;
}
我在代码中添加了一些用于调试目的。 6从未出现过。
String postfix(String infix){
std::vector<String> vec;
vec = infix.split(' ');
Stack<String> tmp;
String right, left, op;
int i = 0;
while (vec[i] != ';'){
std::cout << 1 << std::endl;
if (vec[i] == ')'){
right = tmp.pop();
op = tmp.pop();
left = tmp.pop();
std::cout << 2 << std::endl;
tmp.push(left + ' ' + right + ' ' + op);
std::cout << 3 << std::endl;
}else{
if (vec[i] != '(' && vec[i] != ' ')
std::cout << 4 << std::endl;
tmp.push(vec[i]);
std::cout << 5 << std::endl;
}
++i;
}
std::cout << 6 << std::endl;
String postfix = tmp.pop();
return postfix;
}
输出
-bash-4.1 $进行测试 g ++ -g -Wall -W -Wunused -Wuninitialized -Wshadow -iquote。 -iquote ../string -c test_data3.cpp g ++ -g -Wall -W -Wunused -Wuninitialized -Wshadow string.o test_data3.o -o test_data3 ./test_intStack 一切都很好看。完成测试int堆栈。 ./test_stringStack 一切都很好看。完成测试字符串堆栈。 ./test_data3 (AX +(B * C)); 1 五 1 4 五 1 4 五 1 五 1 4 五 1 4 五 1 4 五 1 2 3 1 2 3 1 4 五 make: * [tests]分段错误(核心转储) rm test_data3.o
答案 0 :(得分:1)
你几乎肯定想从隔离问题开始。
要做到这一点,我首先要做一些重写,将自己的代码用于后缀转换本身,但分别使用std::string
和std::stack
作为字符串和堆栈类型。< / p>
如果这样会导致问题消失,请将其中一个(但不两个)切换回来使用您的课程。如果它仍然有效,请切换另一个使用你的班级。
很可能会很快告诉您问题是在后缀转换,堆栈还是字符串中。一旦你想到这一点,我就可能正在为相关组件编写一些不错的单元测试。
你可以只是在上下文中调试它,但是很可能(至少根据我的经验)这样做会经常留下一些类似的问题,所以下次你尝试时使用它,在稍微不同的情况下你会遇到类似的问题。通过更系统地处理它,您可以消除所有类别的错误,而不是一次删除它们。