0

I am a real c++ beginner and I have a problem with my char array output in a c++ excerise. I was asked to transform a certain UML class in to c++ and generate an working output with the parameters given in main. Here ist the code:

#include <iostream> #include <stdlib.h> /*My class defintion book*/ class Book { protected: long int number; char author[25]; int year; bool lent; void setLent(bool x); bool getLent(); public: Book(long int n, char a[25], int j, bool x); long int getNr(); int getYear(); void print(); }; /*Method definition Book*/ Book::Book(long int n, char a[25], int j, bool x) {number=n; author=a; year=j; lent=x;} long int Book::getNr() {return number; } int Book::getYear() {return year;} void Book::setLent(bool x) {lent=x;} bool Book::getLent() {return lent;} void Book::print() { std::cout << "Book Nr: " << number << std::endl; std::cout << "Author: " << author << std::endl; std::cout << "Year: " << year << std::endl; if (lent==0) std::cout << "Lent [yes/no]: no" << std::endl; else std::cout << "Lent [yes/no]: yes" << std::endl; } /*MAIN*/ int main() { Book b1(123456, "test", 2014, false); b1.print(); system("pause"); return 0; 

This is my output:

Book Nr: 123456 Author: b<Vv-[[vóYA Year: 2014 Lent [yes/no]: no Press any key to continue... 

As you can see all outputs work except for the "Author". There I am getting crap. Note that I have to use char as type. since it is given in the UML class I had to transform into c++.

I really searched everywhere. But didn't find the correct solution. I have the feeling it will be a very simple one...

Thanks in advance for your help!

1
  • author=a; <-- this line in your constructor doesn't do what you think it does. Why aren't you using std::string? Commented Oct 15, 2014 at 22:06

3 Answers 3

1

The reason this doesn't work is that you're assigning your pointer author to another pointer a, which then goes out of scope... so you're left with author pointing to some garbage. If you want to stick with character arrays, you'll have to copy all the data that a points to:

strcpy(author, a); 

But since it's C++, you should just use strings, which are easier to deal with:

class Book { ... std::string author; .... }; Book::Book(long int n, const std::string& a, int j, bool x) : author(a), ... { } 
Sign up to request clarification or add additional context in comments.

6 Comments

Oh it's an array? How does that even compile then?
@Barry: You should better use strncpy(author, a, 25); - and my g++ (version: (Debian 4.4.5-8) 4.4.5) didn't compile the original code from the questioner: original.cpp:25: error: incompatible types in assignment of ‘char*’ to ‘char [25]’
@StefanK. yeah that error is what I'd expect (and get on gcc 4.7.3). And I disagree on strncpy, especially if you're telling it to copy 15 more bytes than author can hold!
Fixed the posting. It's 00:35 am here... don't know where this wrong number came from. ;-)
Hm, should I put that Book book666(666, "Satan overwrites your stack with 666 666 666 666 666 666.... Muhahaha!", 2014, false); into your library?
|
1

You are printing out uninitialized data.

Make author a string

#include <string> class Book { protected: long int number; std::string author; int year; bool lent; 

and make the argument to the constructor a string as well

Book::Book(long int n, const std::string& a, int j, bool x) 

Arrays of characters are not as flexible as std::strings. they are just chunks of data. If you want to use strings then use std::string instead.

Also, use an initializer list in C++ constructors, not java style

Book::Book(long int n, const std::string &a, int j, bool x) : number(n), author(a), year(j), lent(x) { } 

2 Comments

Better yet, make the argument std::string const & a (unless you are going to move-construct Book::author from it).
@Ryan: I don't know if changing from char[25] to std::string is valid. It might be a problem, if the UML says "char[25]". But if it does not, using std::string is of course much better style and less error prone!
0

There are two bugs in your code:

Book::Book(long int n, const char a[25], int j, bool x) { number=n; strncpy(author, a, 25); // author = a; doesn't work! shouldn't compile either... year=j; lent=x; } 

First: The variable author is a pointer to a zero terminated string. You can use strcpy() to copy this string. Therefore you need to #include <memory.h. But you need to be sure that the string -is- really zero-terminated and fits into your target variable! Else you'll overwrite other memory regions next to the target variable, which is also called a buffer overflow! Better use strncpy(target, source, maxlength); which avoids this problem.

Second: Your parameter a should be "const" as you want to be able to call it with a string constant like in Book b1(123456, "test", 2014, false); where "test" is a constant!

As others already suggested you should use std::string instead of a[25]. C-Strings are "C" and not "C++" and you should try to avoid them. C-Strings can introduce a lot of bugs into your code and enable buffer overflows (=security problems), too. Also they are more complicated to handle. You need to #include <string> to use them.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.