Simple stuff... for the life of me can't see where I went wrong

Hi,

Trying to do the simplest of simple c++ project importing from a file, and loading the contents into a vector.
For the life of me, I can't see where I've gone wrong.

The errors are:

||=== Build: Debug in classtest (compiler: GNU GCC Compiler) ===|
/usr/bin/ld: obj/Debug/main.o||in function `main':|
/home/linc/Documents/Workspace/classtest/main.cpp|23|undefined reference to `testStuff::testStuff()'|
/usr/bin/ld: /home/linc/Documents/Workspace/classtest/main.cpp|26|undefined reference to `testStuff::setsomeint(int)'|
/usr/bin/ld: /home/linc/Documents/Workspace/classtest/main.cpp|27|undefined reference to `testStuff::setsomestring(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'|
/usr/bin/ld: /home/linc/Documents/Workspace/classtest/main.cpp|23|undefined reference to `testStuff::~testStuff()'|
/usr/bin/ld: /home/linc/Documents/Workspace/classtest/main.cpp|23|undefined reference to `testStuff::~testStuff()'|
/usr/bin/ld: obj/Debug/main.o||in function `void __gnu_cxx::new_allocator<testStuff>::destroy<testStuff>(testStuff*)':|
/usr/include/c++/9/ext/new_allocator.h|153|undefined reference to `testStuff::~testStuff()'|
/usr/bin/ld: obj/Debug/main.o||in function `void std::_Destroy<testStuff>(testStuff*)':|
/usr/include/c++/9/bits/stl_construct.h|98|undefined reference to `testStuff::~testStuff()'|
||error: ld returned 1 exit status|
||=== Build failed: 8 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|



Can anyone point it out?
(I'm sure that when you do, it'll be "Oh! Yes, of course! How silly of me!")

classtest.h:

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
#ifndef CLASSTEST_H_INCLUDED
#define CLASSTEST_H_INCLUDED

#include <string>

using namespace::std;

class testStuff
{

public:
    testStuff();
    ~testStuff();
    void setsomeint(int);
    void setsomestring(string);
    int returnsomeint(void) const;
    string returnsomestring(void) const;

private:
    int someint;
    string somestring;
};


#endif // CLASSTEST_H_INCLUDED 


classtest.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
#include <iostream>
#include <vector>
#include "classtest.h"
#include <string>

using namespace std;

testStuff::testStuff()
{
    // Nothing to see here
}

testStuff::~testStuff()
{
    // nothing to see here
}

// Mutator function
void testStuff::setsomeint(int number)
{
    someint = number;
}

// Mutator function
void testStuff::setsomestring(string nothery)
{
    somestring = nothery;
}

// Accessor function
int testStuff::returnsomething() const
{
    return someint;
}

// Accessor function
string testStuff::returnanother() const
{
    return somestring;
}


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
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include "classtest.h"

using namespace std;

int main()
{

    vector<testStuff> classystuff;

    fstream infile;
    string intscratch;
    string stringscratch;

    infile.open("infile.txt", ios::in);


    while(!infile.eof())
    {
        testStuff stuff;
        getline(infile, intscratch, ' ');
        getline(infile, stringscratch);
        stuff.setsomeint(stoi(intscratch));
        stuff.setsomestring(stringscratch);
        classystuff.push_back(stuff);
    }

    return 0;
}
Last edited on
You need to compile classtest.cpp and link with classtest.o
@JLBorges - Thank you, but I'm not sure what you mean by this.
I have the 3 files in a Code::Blocks project.
All I usually do, is hit F9 and it compiles it all as a project.
I can't seem to see an option to individually compile and link classtest.cpp on its own.

Can you please elucidate?
Are you saying that the code itself appears sound?

Thanks.
Last edited on
> code itself appears sound?

The code needs fixes; for instance these need to match the declarations in the header:
1
2
3
4
5
6
7
8
9
int testStuff::returnsomething() const 
{
    return someint;
}

// Accessor function
string testStuff::returnanother() const
{
    // ... 

The compiler would have emitted errors if you had actually compiled classtest.cpp
Are you certain that the correct file is included in the project?


And in main.cpp looping on eof is not right: while(!infile.eof())

Also, avoid placing using namespace std; at global namespace scope in a header file.
> And in main.cpp looping on eof is not right: while(!infile.eof())

What's not right about it?
(I'm pretty sure I've used it before and it worked. I have another project that uses it.)
What would you use instead?

> The compiler would have emitted errors if you had actually compiled classtest.cpp
> Are you certain that the correct file is included in the project?

Again, this is not something I've needed to concern myself with before.
I added the files into the project as I have been doing throughout my learning and have not had an issue.
So, to my knowledge, yes, I am reasonably satisfied that it is added.
And, I have never had to specifically compile an individual .cpp file before.
(Hitting F9 usually compiles main.cpp along with and .h and .cpp files altogether.)

I not sure where I have gone wrong here.

Thanks.

Disregard.

I think I've found where I went wrong.

Many thanks.
> What's not right about it?

1
2
3
4
5
6
7
8
9
while(!infile.eof())
{
    testStuff stuff;
    getline(infile, intscratch, ' '); // *** this attempt at input may fail
    getline(infile, stringscratch); // *** this attempt at input may fail
    
    // should be using intscratch and stringscratch only if they were successfully read
    // ...
}



This is the idiomatic way:
1
2
3
4
5
6
while( getline(infile, intscratch, ' ') && getline(infile, stringscratch) )
{
    // if we get here, we know that the input operations were successful
    // we can safely use intscratch and stringscratch.
    // ...
}
Okay, I'll give that a try.

Many thanks.
Topic archived. No new replies allowed.