-1

In this example from The C++ Programming Language 4th edition, chapter 8 I get error char[2] not assignable and char [5] not assignable. I'm using clang 4.9. What am I missing?

struct Address{
       string name;
       int number;
       string street;
       string town;
       char state[2];
       char zip[5];
       Address(const string n,int nu,const string & s,
                   const string& t,const string& st,int z);
};
Address::Address(const string n,int nu,const string & s,
                   const string& t,const string& st,int z)
     :name{n},
      number{nu},
      street{s},
      town{t}
{
  if(st.size()!=2)
        cout<<"state abbreviation should be two characters";
  state={st[0],st[1]};
  ostringstream ost;
  ost<<z;
  string zi{ost.str()};
  switch(zi.size()){
  case 5:
   zip={zi[0],zi[1],zi[2],zi[3],zi[4]};
  break;
  case 4:
   zip={'0',zi[0],zi[1],zi[2],zi[3]};
  break;
  default:
   cout<<"unexpected zip code format";
  }      
}
Peter Hall
  • 53,120
  • 14
  • 139
  • 204
mage
  • 3
  • 5
  • I scream for [MCVE](https://stackoverflow.com/help/mcve)! e.g. `zi` definition is not shown yet. – javaLover May 21 '17 at 08:28
  • 2
    Not nice to have incomplete code here. And in addition, why we have to give tons of parameters to check an internal class init? Please provide a small code snippet! – Klaus May 21 '17 at 08:45
  • Respectfully, I admit to have posted a bit incomplete code earlier but I also tried best before asking i found this relevant but confusing. http://stackoverflow.com/questions/4057948/initializing-a-member-array-in-constructor-initializer – mage May 21 '17 at 09:01

1 Answers1

0

You can't use copy initialisation for c like arrays. Use std::array instead which enables init from initializer list.

Please also notice how small the problem can be described and the solution can be given. You example code is full of useless statements for that problem and makes it not easy to get down to the problem!

Also as a hint it is often a good idea to use braces for if statement blocks, use endline after a print out and do most of the job in the header of a class to get full power of compiler optimizer. Splitting into several units without using link time optimizer will reduce performance and grows you code size without any benefit. Splitting definition and declaration makes sense if you have circular deps. But yes, it is also a matter of taste...

#include <iostream>
#include <string>
using namespace std;

struct Address{
    //char state[2];
    std::array<char,2> state;
    Address( const string& st )
    {
        if(st.size()!=2)
        {
            cout<<"state abbreviation should be two characters" <<std::endl;
            return;
        }

        state={st[0],st[1]};
        std::cout << state[0] << state[1] << std::endl;
    }
};

int main()
{
    Address a{"AB"};
}

~

Klaus
  • 24,205
  • 7
  • 58
  • 113
  • The code i have given is almost verbatim from the book "The c++ programming language, 4th edition" by Bjarne Stroustrup; except the "cout part" . So I suppose the code should work as given. I also went through alternate approach suggested. but i am interested to know if this is correct or incomplete. – mage May 21 '17 at 09:23
  • @mage The book you mentioned has some buggy examples.So what? :-) "So I suppose the code should work as given". Nope! ;) You will learn that also professionals are not free of mistakes. That is the price of a more and more complex world. And again, no need to copy books into questions. Simplify your code snippets please. – Klaus May 21 '17 at 09:45
  • so `state={st[0],st[1]}` used in the example not possible and is a genuine error in the book? @Peterhall I believe structure ,member-variable tag are pertinent to the question. – mage May 21 '17 at 09:59
  • @mage: Feel free to contact Bjarne to report that problem. He provide an errata for his books. Maybe I am wrong with my suggested solution or he is wrong. To clarify, simply write him an email. Errata see: http://www.stroustrup.com/4th_printing3.html – Klaus May 22 '17 at 09:59