defining insertion operator

Pages: 12
hey guys, working on a project for school, and i'm getting 5 errors from one function definition. here's the code i have written for it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
istream &operator >>(istream &inStream, const Paragraph &para)
{
	inStream >> para.wordCount;

	delete [] para.words;  //deallocates arrray

	para.words = new string[para.wordCount];

	string tempPara;
	for(int i = 0; i < wordCount; i++)
		istream >> tempPara.words[i];

	return inStream;

}



in the class, it's a friend, just so it's stated. no idea what i'm doing wrong to have it give me 5 errors when i compile. what i need it to do is: inputs a paragraph from a stream, deallocate/allocate memory as needed. first thing read should be the number of words in the paragraph. and return a reference to the stream passed.

any help is very, very much appreciated.
Last edited on
*sigh*.. please use [ code] tags.
i'm sorry, i don't know how to use [code] tags.
Does your teacher require you to count the amount of words for a paragraph, BEFORE you type it?
I think it is better to read the input line by line. Just define an ending tag, so you know when to stop reading. Something like "If you write an empty line, i will stop reading from keyboard".

I see several logical problems in your code. First obvious one is, that you read the input into a temporary variable, but you never store it in your object. I assume you just forget to allocate & copy it into your 'para' object.

Do you need help with reading linewise input?

Edit:

As it seems you need to allocate words for your temporary object too. Never use 'delete []' without a 'new []'.

That means:

1
2
string tempPara;
tempPara.words = new string[wordCount];


btw. you can use syntax highlighting as i do, if you write [ code] Here your code [/ code] without whitspaces.

Like this:
Here your code


Using dynamic memory allocation within objects can be pretty dangerous. Sometimes you need to rewrite all of the constructors to minimize possible complications. Such as default, copy Constructrors and the assignment operator.
Last edited on
sorry, i thought i had said this. there is a file that has the paragraph already written up that is being opened inside the program through streams.

i'm just not sure how to allocate and copy it into my 'para' object so the rest of the code can read it just fine.

i just gotta make sure to read it word by word from the paragraph file (which is opened in main(), btw)

streams has me all confused, that's why i'm asking for help.

i hope i'm making sense, just getting frustrated with this project.
But be assured that inStream is just only one stream and is not being changed in your process. It can be a file or the keyoard input. It could even be a network connection.

So you are saying the first information in your file cotains how many words have to be read? If not, its not gonna work. But if so, it is a good approach in determining at which point a paragraph is really ending. (Some protocols as HTTP uses bytes not words - but it is still the same good idea)

But why do you use a temp object? Just write the words in your para object, you even allocated memory for this one.
Last edited on
That there is an extraction operator. (You are extracting data from a stream.)

Extraction operators cannot modify const objects. Hence, your prototype should be:

istream &operator >>(istream &inStream, Paragraph &para)


When you get around to writing the insertion operator, it should operate on a const object:

ostream &operator <<(ostream &outStream, const Paragraph &para)

Hope this helps.
@ maikel:

yes, the first information in the file contains how many words are in the paragraph that have to be read.

and on your question on why i'm using a temp object, i thought that's what i had to do? how do i write the words into the para object directly then? i guess that's what i'm confused on.

oh, and thanks for showing me how to use [ code] tags, i appreciate it.

@duoas:

the insertion operator is already written, i apologize for the mix-up in terms. streams have me all turned around for some reason!
so Just use

 
    inStream >> para.words[i]


instead of

 
    inStream >> tempPara.words[i]


The problem is, that you did not allocate memory for tempPara's words. You did for para's words.
So if reading into tempPara should result in Segmentation Fault - if I understand the object correctly.
But that also means, that tempPara is useless, so just remove it from your code.
Last edited on
so i don't even need to declare tempPara and go through all that? i just want to make sure
You still have to go through all words, but without tempPara.

just like this:

1
2
for (int i = 0; i < para.wordCount; i++)
     inStream >> para.words[i];


Check that you use para.wordCount and not wordCount. You dont have declared wordCount anywhere.
wow, i can't believe i missed that in the for statement! lol. i feel like a dummy.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
istream &operator >>(istream &inStream, const Paragraph &para)
{
	inStream >> para.wordCount;

	delete [] para.words;  //deallocates arrray

	para.words = new string[para.wordCount];

	for(int i = 0; i < para.wordCount; i++)
		istream >> para.words[i];

	return inStream;

}


so i changed the code, it all makes sense, but i get 4 errors still:

in reference to line 3 in code i provided here
Error 1 error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'const int' (or there is no acceptable conversion) f:\advancedc++\project 6 (bad libs) chris nelson\bad libs project\main.cpp 196

in reference to line 7 in code i provided here
Error 2 error C2166: l-value specifies const object f:\advancedc++\project 6 (bad libs) chris nelson\bad libs project\main.cpp 200

in reference to line 10 in code i provided here
Error 3 error C2143: syntax error : missing ';' before '>>' f:\advancedc++\project 6 (bad libs) chris nelson\bad libs project\main.cpp 203

in reference to line 10 in code i provided here
Error 4 error C2143: syntax error : missing ';' before '>>' f:\advancedc++\project 6 (bad libs) chris nelson\bad libs project\main.cpp 203
wait wait.... didn't I just answer this?

http://cplusplus.com/forum/beginner/21103/

1 thread please.
You still need to remove the const, as Duoas has mentioned.

1
2
3
4
5
istream &operator >>(istream &inStream, const Paragraph &para)

into

istream &operator >>(istream &inStream, Paragraph &para)


Disch: Afaik this is a different question as in Beginners Forum.
ok, i removed the const, and 7 errors arise now.

such as:

that's in reference to line 3 of the code i last provided.
Error 1 error C2248: 'Paragraph::wordCount' : cannot access private member declared in class 'Paragraph' e:\advancedc++\project 6 (bad libs) chris nelson\bad libs project\main.cpp 194 Bad Libs Project

and:

in reference to line 10 in the code i last provided.
Error 6 error C2143: syntax error : missing ';' before '>>' e:\advancedc++\project 6 (bad libs) chris nelson\bad libs project\main.cpp 201 Bad Libs Project

i don't understand these errors
1.) You misspelled inStream in your for-loop.
2.) Do not forget to change the friend declaration in your class definition. (from const to non-const)
thanks Maikel. i'm now getting 2 more errors i have no idea how to fix:

Error 2 error LNK2019: unresolved external symbol "class Paragraph const __cdecl fillInWords(class Paragraph)" (?fillInWords@@YA?BVParagraph@@V1@@Z) referenced in function _main main.obj Bad Libs Project

and

Error 3 fatal error LNK1120: 1 unresolved externals E:\AdvancedC++\Project 6 Bad Libs Project


any of you guys understand this? i can post the code in it's entirety if needed. just let me know.
I believe these are not problems with this particular piece of code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>

using namespace std;

// Paragraph class definition.
class Paragraph
{
public:
	Paragraph();
	Paragraph(const Paragraph &para);  // copy constructor
	~Paragraph();

	static void setLineLength(int len);

	string &replaceWord(string toReplace, string replaceWith);

	friend ostream &operator<<(ostream &outStream, const Paragraph &para);
	friend istream &operator>>(istream &inStream, Paragraph &para);

	Paragraph &operator =(const Paragraph &para);

	int numWords() const;

	string getWord(int i) const;
	// Precondition: i is zero-based word index: 0 <= i <= numWords()-1
	
private:
	static int lineLength;
	string *words;	// POINTER TO DYNAMICALLY-ALLOCATED ARRAY
	int wordCount;	// ARRAY SIZE
};


// Prototype for function dealing with paragraphs.

const Paragraph fillInWords(Paragraph para);


int main()
{
	Paragraph para;

	// LOAD PARAGRAPH FROM FILE (FIND FILE WITHIN PROJECT FOLDER).
	ifstream paraStream("paragraph.txt");
	paraStream >> para;
	paraStream.close();

	Paragraph versions[2];

	cout << "\nFill in words (no spaces):" << endl;
	versions[0] = fillInWords(para);
	cout << "\nVersion1:" << endl;
	cout << versions[0] << endl;

	cout << "\nFill in different words (no spaces):" << endl;
	versions[1] = fillInWords(para);
	cout << "\nVersion2:" << endl;
	cout << versions[1] << endl;

	int favoriteNum;
	do
	{
		cout << "\nYour favorite version (1 or 2)? ";
		cin >> favoriteNum;
		if (favoriteNum == 1 || favoriteNum == 2)
			break;
		cerr << "Unknown favorite #" << favoriteNum << endl;
	}
	while (true);	

	// SAVE FAVORITE VERSION OF BAD LIB TO FILE "favorite.txt".

	

	cout << "\nPress Enter to exit.";
	// Read a char (any input followed by Enter suffices).
	cin.get();

	return 0;
}


// Definition for function dealing with paragraphs.

const Paragraph fillInWords(Paragraph &para)  // PASS BY VALUE
{
	int i;
	for (i = 0; i < para.numWords(); i++)
	{
		string word = para.getWord(i);

		if (word[0] == '<')
		{
			string replaceWith;
			cout << word << ": ";
			cin >> replaceWith;
			cin.ignore();  // swallow newline
			para.replaceWord(word, replaceWith);
		}
	}

	return para;  // COPY IS RETURNED
}

// Paragraph static member definitions.

int Paragraph::lineLength = 66;

void Paragraph::setLineLength(int len)
{
	lineLength = len;
}

// Paragraph member function definitions.

Paragraph::Paragraph()
: wordCount(0), words(NULL)
{
}

Paragraph::~Paragraph()
{
	delete [] words;
	words = NULL;
	wordCount = 0;
}

ostream &operator <<(ostream &outStream, const Paragraph &para)
{
	// Output number of words in paragraph.
	outStream << para.wordCount << endl;
	int lengthLine = 0;


	int i;

	for (i = 0; i < para.wordCount; i++)
	{
		if (i > 0)
			outStream << ' ';
	}

	return outStream;
}

int Paragraph::numWords() const
{
	return wordCount;
}

string Paragraph::getWord(int i) const
{
	return words[i];
}

Paragraph::Paragraph(const Paragraph &para)
{
	words = new string[wordCount];
	wordCount = para.wordCount;

	int i;
	for (i=0; i < wordCount; i++)
		words[i] = para.words[i];
}

Paragraph &Paragraph::operator =(const Paragraph &para)
{
	if(this != &para)
	{
		delete [] para.words;

		words = new string[wordCount];
		/*wordCount = para.wordCount;*/

		for (int i=0; i < para.wordCount; i++)
			words[i] = para.words[i];
	}
	return *this;
}


istream &operator >>(istream &inStream, Paragraph &para)
{
	inStream >> para.wordCount;

	delete [] para.words;  //deallocates arrray

	para.words = new string[para.wordCount];

	for(int i = 0; i < para.wordCount; i++)
		inStream >> para.words[i];

	return inStream;

}

string &Paragraph::replaceWord(string toReplace, string replaceWith)
{
	toReplace = replaceWith;
	return replaceWith;
}


this is my code in it's entirety. i have no idea where these errors are coming from.
The declaration says:

 
const Paragraph fillInWords(Paragraph para);


whereas the definition

 
const Paragraph fillInWords(Paragraph &para)


The compiler tries to resolve the function and cannot find a proper definition for your declaration.

If you correct this, your code will compile, but i bet with you, you get some trash out if this, because you still have a mistake.

Im not even sure how much sense the const keywork before fillInWords makes.

Hint: Look at replaceWord function. Think about storage types and why this cant work what you have written.
Last edited on
Pages: 12