我无法让我的字符串课程正常工作。我的istream函数似乎读取了数据,并且我确认+ =正在添加字符,但是在第一个字符之后,添加的是垃圾。我已经尝试了一切我能想到的工作。有人可以提供一些有关出错的见解。谢谢。
istream& operator >>(istream& ins, string& target)
{
char newInput;
while (ins && isspace(ins.peek()))
ins.ignore();
target = ("");
//int count = 0;
while (ins && !isspace(ins.peek())) //(ins.peek())))
{
ins >> newInput;
target.operator+=(newInput);
}
return ins;
}
void string::operator +=(char addend)
{
if (this->current_length + 1 > this->allocated)
{
reserve(allocated + 1);
}
sequence[current_length] = addend;
current_length += 1;
}
void string::reserve(size_t n)
{
assert(n > current_length);
char *newSequence = new char[n];
if (n == allocated)
{
return;
}
for (size_t i = 0; i < n; i++)
{
newSequence[i] = sequence[i];
}
//destroy old array
delete[] sequence;
//update capacity
allocated = n;
//point data at new array
sequence = newSequence;
}
完整代码:**
#pragma warning(disable : 4996)
#ifndef MAIN_SAVITCH_CHAPTER4_MYSTRING_H
#define MAIN_SAVITCH_CHAPTER4_MYSTRING_H
#include <cstdlib> // Provides size_t
#include <cassert>
#include <string.h>
#include <iostream>
#include <ctype.h>
#include <algorithm>
using namespace std;
namespace main_savitch_4
{
class string
{
public:
// CONSTRUCTORS and DESTRUCTOR
string(const char str[] = "");
string(const string& source);
~string() { delete[] sequence; }
// MODIFICATION MEMBER FUNCTIONS
void operator +=(const string& addend);
void operator +=(const char addend[]);
void operator +=(char addend);
void reserve(size_t n);
void operator =(const string& source);
// CONSTANT MEMBER FUNCTIONS
size_t length() const { return current_length; }
char operator [ ](size_t position) const;
// FRIEND FUNCTIONS
friend ostream& operator <<(ostream& outs, const string& source);
friend bool operator ==(const string& s1, const string& s2);
friend bool operator !=(const string& s1, const string& s2);
friend bool operator >=(const string& s1, const string& s2);
friend bool operator <=(const string& s1, const string& s2);
friend bool operator > (const string& s1, const string& s2);
friend bool operator < (const string& s1, const string& s2);
private:
char *sequence;
size_t allocated;
size_t current_length;
};
// CONSTRUCTOR for the string class:
// string(const char str[ ] = "") -- default argument is the empty string.
// Precondition: str is an ordinary null-terminated string.
// Postcondition: The string contains the sequence of chars from str.
string::string(const char str[])
{
current_length = strlen(str);
allocated = current_length + 1;
sequence = new char[allocated];
for (size_t i = 0; i < allocated; i++)
{
sequence[i] = str[i];
}
}
string::string(const string& source)
//copy constructor
{
current_length = source.current_length;
allocated = current_length + 1;
sequence = new char[allocated];
for (size_t i = 0; i < allocated; i++) {
sequence[i] = source.sequence[i];
}
}
//~string();
// CONSTANT MEMBER FUNCTIONS for the string class:
// size_t length( ) const
// Postcondition: The return value is the number of characters in the
// string.
//
// char operator [ ](size_t position) const
// Precondition: position < length( ).
// Postcondition: The value returned is the character at the specified
// position of the string. A string's positions start from 0 at the start
// of the sequence and go up to length( )-1 at the right end.
char string::operator [ ](size_t position) const
{
assert(position < length());
return (sequence[position]);
}
// MODIFICATION MEMBER FUNCTIONS for the string class:
// void operator +=(const string& addend)
// Postcondition: addend has been catenated to the end of the string.
//
void string::operator =(const string& source)
{
//string assigned to self
if (sequence == source.sequence)
{
return;
}
if (source.current_length > this->allocated)
reserve(source.current_length);
delete[] sequence;
current_length = source.current_length;
allocated = current_length + 1;
for (size_t i = 0; i < allocated; i++) {
sequence[i] = source.sequence[i];
}
}
void string::operator +=(const string& addend)
{
if (this->current_length + addend.current_length > this->allocated)
{
reserve(current_length + addend.allocated);
}
//copy addend to sequence
for (size_t i = 0; i < addend.current_length; i++)
{
sequence[i + current_length] = addend.sequence[i];
}
current_length = current_length + addend.current_length;
}
// void operator +=(const char addend[ ])
// Precondition: addend is an ordinary null-terminated string.
// Postcondition: addend has been catenated to the end of the string.
void string::operator +=(const char addend[])
{
if (this->current_length + strlen(addend) > this->allocated)
reserve(current_length + strlen(addend));
//copy addend to sequence
for (size_t i = 0; i < strlen(addend); i++)
{
sequence[i + current_length] = addend[i];
}
current_length += strlen(addend);
}
// void operator +=(char addend)
// Postcondition: The single character addend has been catenated to the
// end of the string.
//
void string::operator +=(char addend)
{
if ((this->current_length + 1) > (this->allocated))
{
reserve(allocated + 1);
}
//copy addend to sequence
sequence[current_length] = addend;
current_length += 1;
}
// void reserve(size_t n)
// Postcondition: All functions will now work efficiently (without
// allocating new memory) until n characters are in the string.
void string::reserve(size_t n)
{
assert(n > current_length);
//create new array
char *newSequence = new char[n];
if (n == allocated)
{
return;
}
if (n < current_length + 1)
{
n = current_length + 1;
}
for (size_t i = 0; i < current_length; i++)
{
newSequence[i] = sequence[i];
}
delete[] sequence;
//update capacity
allocated = n;
//point data at new array
sequence = newSequence;
}
//Friend Functions
bool operator ==(const string& s1, const string& s2)
{
return (s1 == s2);
}
bool operator !=(const string& s1, const string& s2)
{
return !(s1 == s2); //(strcmp(s1.sequence, s2.sequence) == 0);
}
bool operator >=(const string& s1, const string& s2)
{
return (s1 >= s2); //(strcmp(s1.sequence, s2.sequence) >= 0);
}
bool operator <=(const string& s1, const string& s2)
{
return (s1 <= s2); //(strcmp(s1.sequence, s2.sequence) <= 0);
}
bool operator > (const string& s1, const string& s2)
{
return (s1 > s2); //(strcmp(s1.sequence, s2.sequence) > 0);
}
bool operator < (const string& s1, const string& s2)
{
return (s1 < s2); // (strcmp(s1.sequence, s2.sequence) < 0);
}
// NON-MEMBER FUNCTIONS for the string class
// string operator +(const string& s1, const string& s2)
// Postcondition: The string returned is the catenation of s1 and s2.
//
string operator +(const string& s1, const string& s2)
{
string temp = s1;
temp = s1 + s2;
return temp;
}
// istream& operator >>(istream& ins, string& target)
// Postcondition: A string has been read from the istream ins, and the
// istream ins is then returned by the function. The reading operation
// skips white space (i.e., blanks, newlines, tabs) at the start of ins.
// Then the string is read up to the next white space or the end of the
// file. The white space character that terminates the string has not
// been read.
//
istream& operator >>(istream& ins, string& target)
{
char newInput;
while (ins && isspace(ins.peek()))
ins.ignore();
target = ("");
while (ins && !isspace(ins.peek())) //(ins.peek())))
{
ins >> newInput;
cout << newInput;
target.operator+=(newInput);
}
return ins;
}
// ostream& operator <<(ostream& outs, const string& source)
// Postcondition: The sequence of characters in source has been written
// to outs. The return value is the ostream outs.
ostream& operator <<(ostream& outs, const string& source)
{
outs << source.sequence;
return outs;
}
//
// void getline(istream& ins, string& target, char delimiter)
void getline(istream& ins, string& target, char delimiter)
{
{
int count = 0;
char newLine;
while (ins)
{
ins.get(newLine);
target.operator+=(newLine);
}
}
}
}
#endif
#pragma once
答案 0 :(得分:0)
必须平衡new[]
和delete[]
。
string::operator=(const string&)
例程是delete[]
序列数组,稍后在保留例程中再次获得delete[]
。
答案 1 :(得分:0)
while (ins && !isspace(ins.peek())) //(ins.peek())))
{
ins >> newInput;
target.operator+=(newInput);
}
在这里:
newInput
newInput
的内容插入target
(出于某种原因直接调用函数)如果下一次阅读失败,您就没有检查,newInput
并不是您认为的。
您只是在之前检查了之前的错误。
也许这样的事情会更适合:
while (true) {
const auto next = ins.peek();
if (!ins) break;
if (isspace(next)) break;
ins >> newInput;
target += newInput;
}
我假设如果peek
成功,那么>>
也会成功,但实际上我可能会在!ins
之前再次检查target +=
1}}行,除非我关注速度。特别是,您应该仔细检查peek()
是否设置 eofbit ,因为我无法记住,如果不记得,您肯定需要另一个if
。