Undefined reference to function

I am getting an Undefined reference to function and I can't figure out why.

The error is: main.cpp|288|undefined reference to `HTML::getHeadAndBody(std::string, std::string*, std::string*)

main.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <windows.h>
#include <string.h>
#include <sstream>
#include <fstream>

class HTML
{
    public:
    static int getHeadAndBody(std::string document, std::string* head, std::string* body);
    static void lowercase(char* in, char* out);
};


main.cpp:
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
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
#include "main.h"

using namespace std;

int getHeadAndBody(std::string document, std::string* head, std::string* body)
{
    //Make a buffer(for storing the tag names e.g. html or title
    char buf[500];
    //Make a integer so we know the current character
    int currchar = -1;
    //Loop until we find the first opening bracket (<)
    for(int i=0; i<document.length(); i++)
    {
        if(document[i] == '<')
        {
            //We have found a <. Set the currchar to the current character, and break from the loop.
            currchar = i;
            break;
        }

    }
    //If the loop did not find a <, the currchar will remain as -1.
    //If currchar is -1, we must exit the function as the html file is not valid.
    if(currchar==-1)
    {
        return 1;
    }
    //Create a count integer for use with the buffer
    int count = 0;
    //Loop until we find the closing bracket (>) or the end of the document.
    while(1)
    {
        //Increment currchar by 1
        currchar++;
        //Check if we have found the closing bracket.
        if(document[currchar] == '>')
            break;
        //Check if we have reached the end of the document. If we have we must exit the function
        //as the html file is not valid because there is no closing bracket.
        if(currchar >= document.length())
            return 1;
        //Store the character in the buffer.
        buf[count] = document[currchar];
        //Increment the count integer by 1 so we use the next buffer char next time.
        count++;
    }
    //Append a null character to the buffer to mark the end of the string.
    buf[count] = '\0';
    //Convert the strings to lower case
    //Create a buflc (buffer lower case) variable to store the lower cased buffer.
    char buflc[500];
    HTML::lowercase(buf, buflc);
    //Check if the tag was an html tag.
    if(stricmp(buflc, "html"))
    {
        //If it isnt we must exit the function as the html file is
        //not valid if the first tag is not a html tag.
        return 1;
    }
    //If the code reaches here, the tag must be html. Increment currchar.
    currchar++;
    //Set count back to 0 so we use the buffer properly.
    count = 0;
    while(1)
    {
        //Check if we have reached the end of the document.
        if(currchar==document.length())
            return 1;
        //Check if we have found the opening bracket.
        if(document[currchar]=='<')
            break;
        //Increment currchar
        currchar++;
    }
    //Set count to 0.
    count = 0;
    while(1)
    {
        //Increment currchar
        currchar++;
        //Check if we have reached the end of the document.
        if(currchar >= document.length())
            return 1;
        //Check if we have found the closing bracket.
        if(document[currchar]=='>')
            break;
        //Put the character in the buffer
        buf[count] = document[currchar];
        //Increment count.
        count++;
    }
    //Append a null character to mark the end of the string.
    buf[count] = '\0';
    //Lowercase
    HTML::lowercase(buf, buflc);
    //Check if the tag is a head tag.
    if(stricmp(buflc, "head"))
    {
        //If not exit the function.
        return 1;
    }
    //Increment currchar.
    currchar++;
    //Loop to get all the characters of the head and store them in the head string.
    while(1)
    {
        count = 0;
        if(currchar >= document.length())
            return 1;
        //Check if we have found a bracket, because it could be the end of the head.
        if(document[currchar]=='<')
        {
            while(1)
            {
                currchar++;
                if(currchar >= document.length())
                    return 1;

                if(document[currchar]=='>')
                {
                    break;
                }

                buf[count] = document[currchar];

                count++;
            }
            buf[count] = '\0';
            //Lowercase
            HTML::lowercase(buf, buflc);
            if(!(stricmp(buflc, "/head")))
            {
                //We have reached the end of the head
                break;
            }
            else
            {
                buf[count] = '\0';
                *head += '<';
                *head += buf;
            }
        }
        *head += document[currchar];
        currchar++;
    }
    //The head is now stored in the string *head

    //Check for body tag
    currchar++;
    count = 0;
    while(1)
    {
        if(currchar >= document.length())
            return 1;
        if(document[currchar]=='<')
            break;
        currchar++;
    }
    count = 0;
    while(1)
    {
        currchar++;
        if(currchar >= document.length())
            return 1;
        if(document[currchar]=='>')
            break;
        buf[count] = document[currchar];
        count++;
    }
    buf[count] = '\0';
    HTML::lowercase(buf, buflc);
    if(stricmp(buflc, "body"))
    {
        return 1;
    }
    //If the code gets to here, the body exists

    currchar++;
    while(1)
    {
        count = 0;
        if(currchar >= document.length())
            return 1;

        if(document[currchar]=='<')
        {
            while(1)
            {
                currchar++;
                if(currchar >= document.length())
                    return 1;

                if(document[currchar]=='>')
                {
                    break;
                }

                buf[count] = document[currchar];

                count++;
            }
            buf[count] = '\0';
            HTML::lowercase(buf, buflc);
            if(!(stricmp(buflc, "/body")))
            {
                //we have reached the end of the body
                break;
            }
            else
            {
                buf[count] = '\0';
                *body += '<';
                *body += buf;
            }
        }
        *body += document[currchar];
        currchar++;
    }
    //The body is now stored in the string *body

    //Check for closing html tag
    currchar++;
    count = 0;
    while(1)
    {
        if(currchar >= document.length())
            return 1;
        if(document[currchar]=='<')
        {
            while(1)
            {
                currchar++;
                if(currchar >= document.length())
                    return 1;

                if(document[currchar]=='>')
                {
                    break;
                }

                buf[count] = document[currchar];

                count++;
            }
            buf[count] = '\0';
            HTML::lowercase(buf, buflc);
            if(!(stricmp(buflc, "/html")))
            {
                //we have reached the end of the html
                break;
            }

        }
        currchar++;
    }
    //We have reached the end of the file and it is valid.
    //We have the head and body stored in the strings head and body.
    return 0;
}

void HTML::lowercase(char* in, char* out)
{
    int i = 0;
    while(1)
    {
        if(in[i]=='\0')
        {
            break;
        }
        out[i] = tolower(in[i]);
        i++;
    }
    out[i] = '\0';
}

int main()
{
    string head, body;
    ifstream htmlfile;
    htmlfile.open("C:\\file.html");
    if(!htmlfile.good())
    {
        cout << "Can't read HTML file";
        return 1;
    }
    string document((std::istreambuf_iterator<char>(htmlfile)), std::istreambuf_iterator<char>());
    //TODO:Fix This
    if(HTML::getHeadAndBody(document, &head, &body))
    {
        cout << "HTML file is valid.\n\nThe head is:\n" << head << "\n\nThe body is:\n" << body;
    }
    return 0;
}

Last edited on
in main.cpp line 4
write int HTML::getHeadAndBody(..)
Really...? You added the scope information to function definition and you get that error?
oh i see!!! i had to put HTML:: onto the definition!!! thanks for spotting that...
Zhuge i didn't do it properly the first time i put another whole line... like this
1
2
3
4
5
6
int HTML::getHeadAndBody(blahblahblah);

int getHeadAndBody(blahblahblah)
{
stuff;
}


but i was meant to do this:
1
2
3
4
5

int HTML::getHeadAndBody(blahblahblah)
{
stuff;
}

^^^works^^^
Last edited on
I see. Glad you were able to figure out your error.
Thanks everyone it is solved :D
Topic archived. No new replies allowed.