0

I have been trying to compile this program for the last hour without success. I cant figure out what is wrong, however, I think there is a problem with the constructor. The whole file is too long to print so I will just print a snippet.

String1.h

#ifndef STRING1_H
#define STRING1_H
#include <iostream>
using std::ostream;
using std::istream;


class String {
    char *str;
    int len;
    static int num_strings;
    static const int CINLIM = 80;
public:

String(const char *s);
String();
String(const String &); //COPY CONSTRUCTOR: PASS-BY-REF ALWAYS
 ~String();
 int length() const {
    return len;
}
 String & operator=(const String &);
String & operator=(const char* );
 char & operator [](int i);
const char & operator [](int i) const;
friend std::istream &operator>>(std::istream & is, String & st);
friend std::ostream &operator<<(std::ostream & os, const String & st);
 static int HowMany();
};

String.cpp

 #include "String1.h"
#include <cstring>
#include "iostream"
using namespace std;


int String::num_strings = 0;

int String::HowMany() {
    return num_strings;
}


String::String(const char* s) {
    len = std::strlen(s);
    str = new char [len + 1];
    std::strcpy(str, s);
    num_strings++;
} 


String::String() {
    len = 4;
    str = new char[1];
   std::strcpy(str, "C++");
    str[0] = '\0';
    num_strings++;
}


String::String(const String & st) {
    num_strings++;
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str, st.str);

}

String::~String() {

    --num_strings;
    delete [] str;
}

String & String::operator =(const String& st) {
    if (this == &st)
        return *this;
    delete [] str;
    len = st.len;
    str = new char [len + 1];
    std::strcpy(str, st.str);
    return *this;
}


String &String::operator=(const char* s) {
    delete[]str;
    len = std::strlen(s);
    str = new char [len + 1];
    std::strcpy(str, s);
    return *this;
} 


char & String::operator [](int i) {
    return str[i];
}

const char & String::operator [](int i) const {
    return str[i];
}


ostream & operator <<(ostream& os, const String& st) {

    os << st.str;
    return os;
}

istream & operator >>(iostream & is, String &st) {
    char temp[String::CINLIM];
    is.get(temp,String::CINLIM);
    if(is)
        st=temp;
    while(is&&is.get()!='\n')
        continue;
    return is;
}

main.cpp

#include <iostream>

#include "String1.h"
using namespace std;

const int ArSize = 10;
const int MaxLen = 81;

int main() {
    String name;
   cout << "Hi what is your name?\n";
   cin >> name;
   cout << "Please enter up to " << ArSize <<
            "sayings <empty line to quit>:\n";

   String sayings[ArSize];
 char temp [MaxLen];
    int i;

    for (i = 0; i < ArSize; i++){
        cout << i + 1 << ":";
    cin.get(temp, MaxLen);

    while (cin && cin.get() != '\n')
        continue;
    if (!cin || temp[0] == '\0')
        break;
    else
        sayings[i] = temp;
  }
    int total = i;
}

The error message I am getting is:

    /usr/bin/make"  -f nbproject/Makefile-Debug.mk dist/Debug/GNU-MacOSX/string
mkdir -p build/Debug/GNU-MacOSX
rm -f build/Debug/GNU-MacOSX/main.o.d
g++    -c -g -MMD -MP -MF build/Debug/GNU-MacOSX/main.o.d -o build/Debug/GNU-MacOSX/main.o main.cpp
mkdir -p dist/Debug/GNU-MacOSX
g++     -o dist/Debug/GNU-MacOSX/string build/Debug/GNU-MacOSX/main.o  
Undefined symbols for architecture x86_64:
  "String::String()", referenced from:
      _main in main.o 
  "operator>>(std::basic_istream<char, std::char_traits<char> >&, String&)", referenced from:
      _main in main.o
  "String::~String()", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/GNU-MacOSX/string] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2

Please can someone let me know what is wrong here. If you need me to post the whole program,instead of the snippet, I will be happy to do so.

jis
  • 75
  • 1
  • 2
  • 10
  • possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – chris Jul 24 '13 at 12:09

2 Answers2

1

First, by default a class access privilege is private. String::CINLIM is private, you can't access it directly. You need to either grant public access to CINLIM or move it out of String class.

char temp[String::CINLIM];   // Error, String::CINLIM is private
is.get(temp,String::CINLIM); // same Error

class String {
    char *str;
    int len;
    static int num_strings;
public:
    static const int CINLIM = 80;  // make CINLIM public. 
                                   // Now you can access String::CINLIM directly
//....
};

Second problem, you declared

std::istream &operator>>(std::istream & is, String & st);
//                            ^^^^^^^^

but your implementation is:

operator >>(iostream & is, String &st)
//          ^^^^^^^^

Update from comment:

You need to link String.o in g++ command

g++ -o dist/Debug/GNU-MacOSX/string \
build/Debug/GNU-MacOSX/main.o build/Debug/GNU-MacOSX/String.o
billz
  • 44,644
  • 9
  • 83
  • 100
  • @jis that's right. your code is quite long, I didn't exact all of them. – billz Jul 24 '13 at 12:25
  • I moved the `String::CINLIM` into the public part of the header file but am still getting the error. DO you know why this is? – jis Jul 24 '13 at 12:28
  • hmm, what's the error message now? It builds cleanly on my Linux – billz Jul 24 '13 at 12:31
  • `Undefined symbols for architecture x86_64: "String::String()", referenced from: _main in main.o "operator>>(std::basic_istream >&, String&)", referenced from: _main in main.o "String::~String()", referenced from: _main in main.o ld: symbol(s) not found for architecture x86_64 collect2: ld returned 1 exit status` – jis Jul 24 '13 at 12:34
  • You just need to link String.o – billz Jul 24 '13 at 12:35
  • Do you know how I can do this using Netbeans? – jis Jul 24 '13 at 13:00
  • Sorry, I don't know Netbeans. – billz Jul 24 '13 at 13:01
1

In 'String1.cpp' you defined the function:

istream & operator >>(iostream & is, String &st)

instead of

istream & operator >>(istream & is, String &st)
Itsik
  • 3,920
  • 1
  • 25
  • 37
  • actually, i can see i have a spelling error in the cpp file for: std::istream &operator>>(std::istream & is, String & st);. I have fixed this but it doesn't make a difference. – jis Jul 24 '13 at 12:23
  • builds fine in vs2012 – Itsik Jul 24 '13 at 13:02