1

Below is my code and then below that the error message. I would appreciate any help. Thank you. The Assignment is as follows:

Modify the provided String class to internally store Pascal strings, which are character arrays that start with a number of characters in the string, followed by those characters, with no terminating null character. That is:

  • str should contain a Pascal string.
  • The constructor created in your Pascal string lab should be included. The normal C-string constructor should also be included, and must convert to Pascal string.
  • The c_str function must convert back to a C string to provide a C string to the user. It is okay to allocate the memory for the string in this function.
  • All other functions must perform correctly given the change to the internal string format.
  • You may not store a C string internally along with the Pascal string.
Pascal.cpp
// Pascal Main cpp


#include <iostream>
#include <algorithm>
#include "Pascal.h"
#include <exception>
using namespace std;
// Default constructor
String::String() {
    arr = new char[1];
    arr[0] = '\0';
    len = 0;
}

// Constructor. Converts a C-string to a String object
String::String(const char *s) {
    len = strlen(s);
    arr = new char[len + 1];
    std::copy(s, s + len + 1, arr);
}

// Copy constructor.
String::String(const String &obj) {
    len = obj.len;
    arr = new char[len + 1];
    std::copy(obj.arr, obj.arr + len + 1, arr);
}

// Move constructor.
String::String(String &&obj) {
    len = obj.len;
    arr = obj.arr;
    obj.arr = nullptr;
}

String::String(const char *str, bool pascal) {
    judge = pascal;
    if (judge) {
        len = strlen(str) - 1;
        const char *temp = str;
        arr = new char[len + 1];
        arr[0] = len + '0';
        for (int i = 1; i <= len; i++) {
            arr[i] = temp[i];
        }

    }
    else {
        len = strlen(str);
        arr = new char[len + 1];
        std::copy(str, str + len + 1, arr);
    }
}

// Destructor
String::~String() {
    if (arr != nullptr)
        delete[] arr;
}

// Assignment operator
String &String::operator=(const String &rhs) {
    delete[] arr;
    len = rhs.len;
    arr = new char[len + 1];
    std::copy(rhs.arr, rhs.arr + len + 1, arr);
    return *this;
}

// Move assignment operator
String &String::operator=(String &&rhs) {
    delete[] arr;
    len = rhs.len;
    arr = rhs.arr;
    rhs.arr = nullptr;
    return *this;
}


// Mutator operator[]
char &String::operator[](int index) {
    // check whether the index is within bounds
    if (index > len || index < 0)
        throw std::out_of_range("Index out of range");
    return arr[index];
}

// Accessor operator[]
char String::operator[](int index) const {
    // check whether the index is within bounds
    if (index > len || index < 0)
        throw std::out_of_range("Index out of range");
    return arr[index];
}

// Get the length (number of characters) of a String object
int String::length() const {
    return len;
}

bool operator==(const String &lhs, const String &rhs) {
    if (lhs.judge != rhs.judge) {
        cout << "can't compare";
    }
    return strcmp(lhs.arr, rhs.arr) == 0;
}

bool operator<(const String &lhs, const String &rhs) {
    if (lhs.judge != rhs.judge) {
        cout << "can't compare";
    }
    return strcmp(lhs.arr, rhs.arr) < 0;
}

// Friend functions for > comparison
bool operator>(const String &lhs, const String &rhs) {
    if (lhs.judge != rhs.judge) {
        cout << "can't compare";
    }
    return rhs < lhs;
}

// Friend functions for <= comparison
bool operator<=(const String &lhs, const String &rhs) {
    if (lhs.judge != rhs.judge) {
        cout << "can't compare";
    }
    return !(rhs < lhs);
}

// Friend functions for >= comparison
bool operator>=(const String &lhs, const String &rhs) {
    if (lhs.judge != rhs.judge) {
        cout << "can't compare";
    }
    return !(lhs  < rhs);
}

// Friend functions for != comparison
bool operator!=(const String &lhs, const String &rhs) {
    if (lhs.judge != rhs.judge) {
        cout << "can't compare";
    }
    return !(lhs == rhs);
}

//  Friend function for string concatination
String operator+(const String &lhs, const String &rhs) {
    if (lhs.judge == rhs.judge && lhs.judge == false) {
        int strLength = lhs.len + rhs.len + 1;
        char *tmpStr = new char[strLength];
        for (auto i = 0; i < lhs.len; ++i)
            tmpStr[i] = lhs.arr[i];
        for (auto i = 0; i <= rhs.len; ++i)
            tmpStr[lhs.len + i] = rhs.arr[i];
        String retStr(tmpStr);
        delete[] tmpStr;
        return retStr;
    }
    else if (lhs.judge == rhs.judge && lhs.judge == true) {
        int strLength = lhs.len + rhs.len + 1;
        char *tmp = new char[strLength];
        for (auto i = 1; i <= lhs.len; ++i)
            tmp[i] = lhs.arr[i];
        for (auto i = 1; i <= rhs.len; ++i)
            tmp[lhs.len + i] = rhs.arr[i];
        tmp[0] = (lhs.len + rhs.len) + '0';
        String retStr(tmp);
        delete[] tmp;
        return retStr;
    }
    else {
        return String("can't do that");
    }
}

// Return C style character string
const char* String::c_str() const {
    return arr;
}

//  Friend function for output
std::ostream& operator<<(std::ostream &out, const String &obj) {
    return out << obj.c_str();
}
Pascal.h
// Pascal Header File

#pragma once
#ifndef __MYSTRING_H__
#define __MYSTRING_H__

#include <iostream>

class String {
public:
    // Usage: String aStringObj; or String aStringObj();
    String();

    // Constructor. Converts a char* object to a String  object
    // Usage: String aStringObj("hello"); or String aStringObj = "hello";
    String(const char *s);

    // Copy and move constructors.
    // Usage: String aStringObject(anotherStringObj); or
    // String aStringObject = anotherStringObj;
    String(const String &s);
    String(const char *str, bool pascal);
    String(String&& obj);

    // Destructor
    ~String();

    // Assignment operator
    // Usage: aStringObject = anotherStringObj; or
    // aStringObject.operator=(anotherStringObj);
    String &operator=(const String &rhsObject);
    String& operator=(String&& rhs);

    // Mutator operator[]
    // Usage: aStringObject[1] = ’M’;
    char &operator[] (int index);

    // Accessor operator[]
    // Usage: char ch = aStringObject[1];
    char operator[] (int index) const;

    // Get the length (number of characters) of a String object
    // Usage: int len = aStringObject.Length();
    int length() const;

    // Friend functions for == comparison
    // Usage: if (aStringObject == anotherStringObj) {...} or
    //        if (aStringObject == "hello") {...} or
    //        if ("hello" == aStringObj) {...} or
    friend bool operator==(const String &lhsObject, const String &rhsObject);

    // The other five comparison operators
    // !=, <, >, <=, >= are similarly handled as in line 13.

    friend bool operator<(const String &lhsObject, const String &rhsObject);
    friend bool operator>(const String &lhsObject, const String &rhsObject);
    friend bool operator<=(const String &lhsObject, const String &rhsObject);
    friend bool operator>=(const String &lhsObject, const String &rhsObject);
    friend bool operator!=(const String &lhsObject, const String &rhsObject);

    // Friend function for string concatenation
    // Usage: StringOne = StringTwo + StringThree  or
    //        StringOne = "hello" + StringTwo  or
    //        StringOne = StringTwo + "hello"
    friend String operator+(const String &lhs, const String &rhs);

    // Return C style character string
    // Usage: const char *str = aStringObj.C_str();
    const char *c_str() const;

    // Friend function for output
    // Usage: cout << aStringObj;
    friend std::ostream &operator<<(std::ostream &out, const String &obj);

private:
    // arr implements the String object as a dynamic array
    char *arr;

    // len keeps track of the length
    int len;

    // judge weather the String is a c_string or a pascal_string
    bool judge;
};

#endif

When compiling I get these warnings and errors:

enter image description here

Severity    Code    Description Project File    Line    Suppression State
Warning C4996   'std::_Copy_impl': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'    Pascal Assignment   c:\program files (x86)\microsoft visual studio 14.0\vc\include\xutility 2229    

 Severity   Code    Description Project File    Line    Suppression State
Error   LNK1120 1 unresolved externals  Pascal Assignment   C:\Users\Danielle\Documents\Visual Studio 2015\Projects\Pascal Assignment\Debug\Pascal Assignment.exe   1   

Severity    Code    Description Project File    Line    Suppression State
Error   LNK2019 unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ)   Pascal Assignment   C:\Users\Danielle\Documents\Visual Studio 2015\Projects\Pascal Assignment\MSVCRTD.lib(exe_main.obj) 1   
Ken White
  • 123,280
  • 14
  • 225
  • 444
danie
  • 31
  • 5
  • 1
    I do love images that are unreadable. Please cut'n'paste the relevant text – Ed Heal Apr 11 '16 at 23:42
  • I can see it, can you not? If you click on the image it brings up a bigger version. I can try again. – danie Apr 11 '16 at 23:45
  • it appears you don't have a main function... that is required to run your application. I would suggest creating a main.cpp with a [main function](http://stackoverflow.com/a/4207223/332733) – Mgetz Apr 11 '16 at 23:45
  • I suspect either you didn't define a `main()` function, or you didn't `#include "stdafx.h"` given you are using Visual Studio. – Dafang Cao Apr 11 '16 at 23:45
  • I do have a main function but it's just naming the class. The errors read like this: 1>------ Build started: Project: Pascal Assignment, Configuration: Debug Win32 ------ – danie Apr 11 '16 at 23:46
  • 1
    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) – Deqing Apr 11 '16 at 23:47
  • 1
    @danie it's not in the code you've posted, you need a function with the signiture of `int main(int argc, char** argv)` – Mgetz Apr 11 '16 at 23:47
  • 1
    @danie - It is good manners to make life easy for us. You can cut'n'paste the error. Some of us are on mobile devices – Ed Heal Apr 11 '16 at 23:49
  • Okay, I can't seem to cut and paste the error message. I'm trying my best. @Mgetz can you explain why please? – danie Apr 11 '16 at 23:51
  • @DafangCao I've not used the stdafx.h before. What does it include? – danie Apr 11 '16 at 23:53
  • main is the entrypoint from the C++ runtime library into your application, without it the runtime library can't start your application. – Mgetz Apr 11 '16 at 23:55
  • @danie - You can edit the question to put in the extra detail (and that enables one to make it more readable) – Ed Heal Apr 11 '16 at 23:56
  • Off topic: I don't think this is harmful, but it's not necessary to have both. `#pragma once` and `#ifndef __MYSTRING_H__`. Basically, pick one. Read more here: https://en.wikipedia.org/wiki/Include_guard – user4581301 Apr 11 '16 at 23:56
  • @ Ed Heal will do. – danie Apr 11 '16 at 23:58
  • @danie If you have `int _tmain(int argc, _TCHAR* argv[])` in a file, add `#include "stdafx.h"` in said file. Otherwise Mgetz's solution is the way to go. – Dafang Cao Apr 12 '16 at 00:03
  • Useful help for next time: Down at the bottom of the Error List pane are two tabs. One Is Error List which is giving you grief. It's the default and graphical. The second is Output. Output gives you cut-and-paste-able text of all of the error messages so you don;t have to retype them. – user4581301 Apr 12 '16 at 00:05
  • The warnings are just Visual C++ sillywarnings. Over at Microsoft they once got the (erroneous!) idea that a lot of C standard library functions had been "deprecated", and they let the compiler so inform users. After a storm of negative feedback they changed the wording a little, but still you have to e.g. define **`_SCL_SECURE_NO_WARNINGS`** to get rid of these warnings. – Cheers and hth. - Alf Apr 12 '16 at 00:09
  • Useful help. Problem solved! – danie Apr 12 '16 at 00:12
  • @danie - Gave you a +1 for improving the question. Please take note in future – Ed Heal Apr 12 '16 at 00:17

1 Answers1

2

The lack of a main function is because you haven't defined one, and you're compiling as a program. Either this should be a library project, or there should be a main function. The #endif at the end of your code indicates that this is a header where the start of it just isn't shown. If so then yYou need a separate .cpp file (for example) to put your main in.


In other news:

  • Identifiers that contain two successive underscores, like __MYSTRING_H__, are reserved to the implementation and can therefore cause trouble. Also, an identifier starting with underscore followed by uppercase, is reserved. Use e.g. just MYSTRING_H. But:

  • When you use #pragma once, as you do, then you don't need include guard symbols.

  • I haven't really studied the code, but unless you use operations like <<, or e.g. endl, in the header, then you don't need to include the entire <iostream> in the header. It's sufficient to include <iosfwd>. That's what its for: a lean & mean just declarations of relevant types. You still need to include <iostream> where you use the standard streams, i.e. in your implementation file. But this cost is not charged to client code.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • I did have a main.cpp file. I just didn't show it because it had nothing but the include the header file in it. – danie Apr 12 '16 at 00:17
  • Okay, just add `int main(){}`, which is the shortest possible `main`. – Cheers and hth. - Alf Apr 12 '16 at 00:19
  • Re striked-out text in this answer: after studying the code I found that it was both an implementation file and a header, concatenated. I edited the question to separate them and add filename headers. Then add strike-out. – Cheers and hth. - Alf Apr 12 '16 at 00:21