Problem with some compiler messages....

Hello everybody!!
I have written a program but I cant overcome some compiler messages.
Here is the 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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
#include <cstdlib>

#include <iostream>

#include <fstream>

#include <vector>

#include <string>

#include <map>

using namespace std;



void fill_up(vector <string> &v,ifstream &f)

{

     string temp=" ";

     while(getline(f,temp))

      {

       int i=0;

       v[i]=temp;

       i++;

      }



}



string loadMsg(string filename)

{

    string str="",temp;

    ifstream inFile(filename);
//The first mistake appears here
    while(inFile>>temp)

    {

        str+=temp;



    }



    return str;

}







string analyzeSpamMsg(string s,string wanted,map<string,unsigned> &t_Map,string fName)

{

   int x = 0;

   do

    { x = s.find(wanted,x);

          if (x != string::npos)

        {

		t_Map[wanted]++;

          x += wanted.length();

        }

    }

   while (x != string::npos);



   map<string, unsigned>::const_iterator mapIterator;

   int features=0,id=0;

   string ret;

   for(mapIterator=t_Map.begin();mapIterator!=t_Map.end();mapIterator++)

   {

      if((*mapIterator).second!=0)

	  {

	     features++;



	  }



	  for(mapIterator=t_Map.begin();mapIterator!=t_Map.end();mapIterator++)

	  {

	    id++;

		ret="<message="+"\""+fName+"\""+" category="+"\""+"spam"+"\""+" features="+"\""+features+"\""+">"+"\n";
//the second mistake is here
		if((*mapIterator).second!=0)

		{

		   ret+="<feature id="+"\""+id+"\""+" freq="+"\""+((*mapIterator).second)+"\""+">"+((*mapIterator).first)+"</feature"+"\n";
//the third is here
		}



	  }



   }



   return ret;



}











string analyzeLegMsg(string s,string wanted,map<string,unsigned> &t_Map,string fName)

{

   int x = 0;

   do

    { x = s.find(wanted,x);

          if (x != string::npos)

        {

		t_Map[wanted]++;

          x += wanted.length();

        }

    }

   while (x != string::npos);



   map<string, unsigned>::const_iterator mapIterator;

   int features=0,id=0;

   string ret;

   for(mapIterator=t_Map.begin();mapIterator!=t_Map.end();mapIterator++)

   {

      if((*mapIterator).second!=0)

	  {

	     features++;



	  }



	  for(mapIterator=t_Map.begin();mapIterator!=t_Map.end();mapIterator++)

	  {

	    id++;

		ret="<message="+"\""+fName+"\""+" category="+"\""+"legit"+"\""+" features="+"\""+features+"\""+">"+"\n";
//the //forth mistake is here
		if((*mapIterator).second!=0)

		{

		   ret+="<feature id="+"\""+id+"\""+" freq="+"\""+((*mapIterator).second)+"\""+">"+((*mapIterator).first)+"</feature"+"\n";
//the //last mistake is here
		}



	  }



   }



   return ret;



}





 void showResults(const vector<string> &printVec)

{

    for(unsigned i=0;i<printVec.size();i++)

    {

        cout<<printVec[i]<<endl;
}

}



I have spelt many hours to understand what my mistakes exactly are but I cant find them.

P.S:the program reads some data from files so please ignore the compiler messages which mention that they cant find the file.The mistakes I want a piece of help are mentioned by comments.I also use gcc compiler(windows OS).

I would be very grateful if you could help me...
Last edited on
hello,

I'll start with your last mistakes.

the main problem is that you can not treat pointers as intuitively as you would like, like with objects of the string class.

your compiler error " can not add 2 pointers" happens because of your following piece of code

ret="<message="+"\"";

here, both "message" and "\"" are just 2 pointers of type const char*.

and string concatenation doesn't work with char pointers.

you have 2 options to resolve this:

or use the strcat - function of the C-libraries

#include <string.h>
char buffer[100];
buffer[0] = '\0';
ret = strcat(buffer, "message");
ret = strcat(buffer, "\"");

or, and that's probably what you'll prefer use the string-objects of the Cpp- stl libraries:
string squote ="\"";
string message ="message";
string cppfilename = squote + message + squote;
cout << cppfilename;


your first problem
ifstream inFile(filename));

try instead
ifstream inFile(filename.c_str());


hth
Chris
first of all thanks for your useful answer.Just to ensure my learnings from your post...
In the concatenation proccess all I have to change is the "\"" to string?I didnt understood why do I have to make a string variable with the "message" value and not to leave iti as-is(an anonymous string)
I have just made some changes according to chris post.The problem with the filename solved.But I still have some problems with the concatenation.Please take a look in my code and help me with a possible solution.

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
string analyzeSpamMsg(string s,string wanted,map<string,unsigned> &t_Map,string fName)
{
   int x = 0;
   do
    { x = s.find(wanted,x);
          if (x != string::npos)
        {
		t_Map[wanted]++;
          x += wanted.length();
        }
    }
   while (x != string::npos);

   map<string, unsigned>::const_iterator mapIterator;
   int features=0,id=0;
   string ret,squote="\"",message="<message",category=" category=",spam="spam",sFeatures="features",close_tag=">",endline="\n";
   string feature_id="feature id=",frequency=" freq=",end_feature="</feature>";
   for(mapIterator=t_Map.begin();mapIterator!=t_Map.end();mapIterator++)
   {
      if((*mapIterator).second!=0)
	  {
	     features++;

	  }

	  for(mapIterator=t_Map.begin();mapIterator!=t_Map.end();mapIterator++)
	  {
	    id++;
		ret=message+squote+fName+squote+category+squote+spam+squote+sFeatures+squote+features+squote+close_tag+endline;
		if((*mapIterator).second!=0)
		{
		   ret+=feature_id+squote+id+squote+frequency+squote+((*mapIterator).second)+squote+close_tag+((*mapIterator).first)+end_feature+endline;
		}

	  }

   }

   return ret;

}


What I am doing wrong?
cppchris way of concatenating seperate strings together is ok but long winded. I'll show another way in a minute.
But you made some mistakes as follows:
1. features is an int. In the middle of adding all those strings you have inserted an integer. You cannot add a integer to a string.
Same for id and mapIterator.second
First you have to create the string representation of the integer and add that.

Ways of adding strings and char literals - Method 1.
If you want to do this:
string result = "some text" + "this text" + "this text"
then you can write it like this:
string result = string("some text" )+ string("this text") + string("this text")

Ways of adding strings and char literals - Method 2.
Same as method 1 but less typing.
If you want to do this:
string result = "some text" + "this text" + "this text"
then you can write it like this:
string result = string("some text" ) + "this text" + "this text"
Notice you only have to turn the first one into a string.

How to get the ascii text representation of an decimal number
You can use stringstream for this:
1
2
3
4
5
6
7
8
template <typename T>
string valToString(T val)
{
    stringstream ss;
    ss << val;
    
    return ss.str();
}



PS. You are re-setting int i to 0 inside the while loop.
So i won't become greater than 1



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
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <sstream>

using namespace std;

template <typename T>
string valToString(T val)
{
    stringstream ss;
    ss << val;
    
    return ss.str();
}


void fill_up(vector <string> &v,ifstream &f)
{
     string temp;

     int i =0;
     while(getline(f,temp))

      {
            //int i =0; Move this outside the loop - otherwise it will always reset
            v[i]=temp;
            i++;
      }
}


string loadMsg(string filename)
{
    string str, temp;

    ifstream inFile(filename.c_str());

    while(inFile>>temp)

    {
        str+=temp;
    }

    return str;

}

string analyzeSpamMsg(string s,string wanted,map<string,unsigned> &t_Map,string fName)
{

   int x = 0;

   do

    { 
        x = s.find(wanted,x);

        if (x != string::npos)

        {
            t_Map[wanted]++;
            x += wanted.length();
        }

    }

   while (x != string::npos);

   map<string, unsigned>::const_iterator mapIterator;
   int features=0,id=0;
   string ret;
   

   for(mapIterator=t_Map.begin();mapIterator!=t_Map.end();mapIterator++)

   {

      if((*mapIterator).second!=0)

      {

         features++;
      }

      for(mapIterator=t_Map.begin();mapIterator!=t_Map.end();mapIterator++)

      {

        id++;
        ret= string("<message=")+"\""+ fName + "\"" + " category=" + "\"" + "spam" + "\"" + 
        " features=" + "\"" + valToString(features) + "\""+">"+"\n";

        if((*mapIterator).second!=0)

        {
           ret+= string("<feature id=")+"\""+ valToString(id) +"\""+ 
           " freq="+"\""+ valToString((*mapIterator).second)+"\""+
           ">"+((*mapIterator).first)+"</feature"+"\n";

        }

      }

   }

   return ret;
}


string analyzeLegMsg(string s,string wanted,map<string,unsigned> &t_Map,string fName)
{

   int x = 0;

   do

    { x = s.find(wanted,x);

          if (x != string::npos)

        {

        t_Map[wanted]++;

          x += wanted.length();

        }

    }while (x != string::npos);
    
    
   map<string, unsigned>::const_iterator mapIterator;

   int features=0,id=0;
   string ret;

   for(mapIterator=t_Map.begin();mapIterator!=t_Map.end();mapIterator++)

   {

      if((*mapIterator).second!=0)

      {
         features++;
      }

      for(mapIterator=t_Map.begin();mapIterator!=t_Map.end();mapIterator++)

      {

        id++;
        ret= string("<message=")+"\""+fName+"\""+" category="+"\""+"legit"+"\""+
        " features="+"\""+ valToString(features) +"\""+">"+"\n";

        if((*mapIterator).second!=0)

        {
           ret+= string("<feature id=") +"\""+ valToString(id) +"\""+" freq="+"\""
           + valToString( ((*mapIterator).second) )+"\""+">"+((*mapIterator).first)
           +"</feature"+"\n";
        }

      }

   }

   return ret;

}
Dear guestgulkan,
As I have not been taught templates yet and so I dont think it is a good practice for now,does it make any difference to just write some_int.str()?
I confess that I didnt know that I couldn concat strings and integers in the "simple" way,as Java does for example...
Last edited on
That's the problem:
1
2
int a = 3;
string astr = a.str(); // NO SUCH THING 


I did the template to save typing.

Normally You would have to write one (or possibly more) functions of you own to
get a string representation of a numeric type (int, unsigned, double) or maybe use the library functions itoa, ltoa etc..)
However, in C++ the stringstream can do that for you.

So if you are not happy having the template function there, you can do
like this instead:
Say you have an int called id:

1
2
3
4
5
6
#include <sstream> //need to include this

stringstream  sstream;
string text;
sstream <<  id;
text = sstream.str();



Last edited on
Is it possible to concat with the operator <<?
I tried your solution and it works perfectly but I am a bit hesitated to use things that have not taught.I hope you understand me
Last edited on
OK, I perfectly understand your reluctance to use something that you haven't been taught yet.
So we will remove the template function and use C++ stringstream class to get us the text represntation of numbers (after all that is what it is there for).
I will use the string analyzeSpamMsg(string s,string wanted,map<string,unsigned> &t_Map,string fName) to show you how.

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
string analyzeSpamMsg(string s,string wanted,map<string,unsigned> &t_Map,string fName)
{

   int x = 0;

   do

    { 
        x = s.find(wanted,x);

        if (x != string::npos)

        {
            t_Map[wanted]++;
            x += wanted.length();
        }

    }

   while (x != string::npos);

   map<string, unsigned>::const_iterator mapIterator;
   int features=0,id=0;
   string ret;
   

   for(mapIterator=t_Map.begin();mapIterator!=t_Map.end();mapIterator++)

   {

      if((*mapIterator).second!=0)

      {

         features++;
      }

      for(mapIterator=t_Map.begin();mapIterator!=t_Map.end();mapIterator++)

      {

        stringstream ssFeatures, ssID, ssMapSecond; //create some stringstreams

        id++;
              
        ssFeatures << features; //make string version of features
        ret= string("<message=")+"\""+ fName + "\"" + " category=" + "\"" + "spam" + "\"" + 
        " features=" + "\"" + ssFeatures.str() + "\""+">"+"\n";

        if((*mapIterator).second!=0)

        {
           ssID << id;//make string version of id
           ssMapSecond << ((*mapIterator).second);//make string version of mapIterator.second
           
           ret+= string("<feature id=")+"\""+ ssID.str() +"\""+ 
           " freq="+"\""+ ssMapSecond.str()+"\""+
           ">"+((*mapIterator).first)+"</feature"+"\n";

        }

      }

   }

   return ret;
}


Now you see how it is done, see if you can modify the
string analyzeLegMsg(string s,string wanted,map<string,unsigned> &t_Map,string fName) function by yourself
guestgulkan you saved me from many headaches and probably some broken monitors:P
Thank you both for your help.It was very useful
Hello,again.Good to see you guys!

I have some more problems on understanding what the compiler wants to say.

I hane two files one header and one cpp file.In the header file I declare my class with its methods.I define them(writing their body) in the cpp.

One of them is operator<<
It's header in .h file is

friend ostream& operator<<(ostream& out, const Instance& inst);

and in cpp it's body is

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ostream& Instance::operator<<(ostream& out, const Instance& inst)
{
    string sq="\"";
    string stringCat="legit";
    if(inst.getCategory())
    {
        stringCat="spam";
    }
    
    out<<"<message file="+sq+inst.getFileName()+sq+" category=" +sq+stringCat+sq+" features="+sq+inst.convertToString(inst.getLength())+sq+">"<<endl;

    for(unsigned i=0;i<inst.getLength();i++)
    {
        out<<"feature id="+sq+inst.convertToString(inst.getLength())+sq+" freq="+sq+inst.convertToString(inst.getFrequency(i))+sq+">"+inst.convertToString(inst.getFeature(i))+"<\feature"<<endl;

    }

    out<<"<\message>"<<endl;

    return out;


}


the convertToString method is declarated in .h fie

Compiler says that:"operator<<(....) must take exactly one argument"

and

"no operator<< (...) memeber function had been declared in class Instance"

Every idea would be helpful to me.thanks in advance.
Instance::operator << ( whateveryouwant );
has to be used:
1
2
Instance myInstance;
myInstance << whateveryouwant;


the operator you want to overload should work like this:
1
2
Instance myInstance;
cout << myInstance;


So just make it as non-member:
1
2
3
4
ostream& operator<<(ostream& out, const Instance& inst)
{
    // your implementation
}

Last edited on
EDIT:
I have one last question.
I have a private class method in .h file.The method is convertToString(unsigned) and is written some posts up:

1
2
3
4
stringstream  sstream;
string text;
sstream <<  id;
text = sstream.str();


I have an error "no matching function for call to..."
what are the possible mistakes?
Last edited on
Are you including <sstream>? Other then that...it should work fine...
Ok,I found it.Wrong argument was the mistake.
thanks for help anyway
Topic archived. No new replies allowed.