0

learning in my c++ the use of copy constructors etc. we were given a template of a program we were to complete, however my output is throwing funky asci characters in my output stream.

Heres my main class:

#include <iostream>
using namespace std;
#include "Contact.h"
using namespace sict;

    int main(){
      Contact c("Empty Contact", 3);
      c.display();
      cout << "Enter Contact information: " << endl;
      c.read();
      c.display();
      cout << endl;
      for (int i = 0; i < 1000000; i++){
        Contact temp("Testing the contact with a looooong "
                     "name that should be taken care of", 20);
        if (!(i % 100000)){
          cout << i << ":" << endl;
          temp.display();
        }
      }
      return 0;
    }

Contact.cpp:

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

namespace sict{


  void Contact::display()const{
    //display the name and go to new line
      cout<< _name << endl;
    // loop through elements of _pn up to _noPN and display them one by one
      for(int i = 0; i < _noPN ; i++){
      _pn[i].display();
      }
    // draw a 40 char line using '-' and go to new line
   cout<<"----------------------------------------"<<endl;


  }
    Contact::Contact(){
        _pn = nullptr;
    }
    Contact::Contact(const char* name, int number){
        strncpy(_name, name,40);
        _pn = new PhoneNumber[number];
        _noPN = number;

    }
    Contact::~Contact(){
         delete[] _pn;

    }


  void Contact::read(){
    cout << "Contact Name: ";
    cin.getline(_name, 41, '\n');
    cout << "Please enter " << _noPN << " phone numbers: " << endl;
    for (int i = 0; i < _noPN; i++){
      cout << i + 1 << ": ";
      _pn[i].read();
    }
  }



  bool Contact::isEmpty()const{
    return _pn == (PhoneNumber*)0;
  }
  void Contact::setEmpty(){
    _name[0] = 0;
    _noPN = 0;
    _pn = (PhoneNumber*)0;// same as _pn = nullptr;
  }
}

Output malfunction:

Empty Contact
----------------------------------------
Enter Contact information:
Contact Name: John Doe
Please enter 3 phone numbers:
1: Home, 123 1234567
2: Cell, 234 2345678
3: Work, 345 3456789
John Doe
Home..........., 123 123-4567
Cell..........., 234 234-5678
Work..........., 345 345-6789
----------------------------------------
    0:
    Testing the contact with a looooong nameôoc·lÐ
    ----------------------------------------
    100000:
    Testing the contact with a looooong nameôoc·lÐ
    ----------------------------------------
    200000:
    Testing the contact with a looooong nameôoc·lÐ
    ----------------------------------------
    300000:
    Testing the contact with a looooong nameôoc·lÐ
    ----------------------------------------
    400000:
    Testing the contact with a looooong nameôoc·lÐ
    ----------------------------------------
    500000:
    Testing the contact with a looooong nameôoc·lÐ
    ----------------------------------------
    600000:
    Testing the contact with a looooong nameôoc·lÐ
    ----------------------------------------
    700000:
    Testing the contact with a looooong nameôoc·lÐ
    ----------------------------------------
    800000:
    Testing the contact with a looooong nameôoc·lÐ
    ----------------------------------------
    900000:
    Testing the contact with a looooong nameôoc·lÐ
    ----------------------------------------

What it is suppose to look like:

Empty Contact
----------------------------------------
Enter Contact information:
Contact Name: John Doe
Please enter 3 phone numbers:
1: Home, 123 1234567
2: Cell, 234 2345678
3: Work, 345 3456789
John Doe
Home..........., 123 123-4567
Cell..........., 234 234-5678
Work..........., 345 345-6789
----------------------------------------

0:
Testing the contact with a looooong name
----------------------------------------
100000:
Testing the contact with a looooong name
----------------------------------------
200000:
Testing the contact with a looooong name
----------------------------------------
300000:
Testing the contact with a looooong name
----------------------------------------
400000:
Testing the contact with a looooong name
----------------------------------------
500000:
Testing the contact with a looooong name
----------------------------------------
600000:
Testing the contact with a looooong name
----------------------------------------
700000:
Testing the contact with a looooong name
----------------------------------------
800000:
Testing the contact with a looooong name
----------------------------------------
900000:
Testing the contact with a looooong name
----------------------------------------

As you can see, theres a few ascii characters being added at the end of name

I can add the rest of the program however it is quiet lengthy, if it is requested i will edit this post and add them.

andirew
  • 23
  • 1
  • 5
  • Without the `Contact` class definition, we really can't help. That's obviously where the problem is. – owacoder Oct 14 '15 at 17:20
  • You need to show the `Contact` constructor - the problem is very likely there (and likely a missing null-terminator for a string). – Rostislav Oct 14 '15 at 17:20
  • Looks like a non-terminated string. – user4581301 Oct 14 '15 at 17:22
  • Seems like your professor has explicitly used a name that is longer than 40 characters. – Bo Persson Oct 14 '15 at 17:22
  • Fiendish! Seeing as the point of the assignment is copy constructors, I assume using std::string is off the table? Two other notes: I see 40 and 41 in the code. You probably want to enforce the buffer size more tightly. If `_name`'s size is changed, 40 will not change, but `sizeof(_name)` will. Give [What is The Rule of Three?](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) a read while on the subject of copy constructors. It'll probably save you some future problems. – user4581301 Oct 14 '15 at 18:06

1 Answers1

1

strncpy(_name, name,40); doesn't add a null-terminator at the end of string. To fix it, just add a line _name[40] = '\0'. For short strings it just happens to copy it. For longer strings - it stops at 40'th symbol.

From cppreference

If count is reached before the entire array src was copied, the resulting character array is not null-terminated.

Rostislav
  • 3,857
  • 18
  • 30