1

How to concatenate to char* in C++? i tried using strcat but that only works for char* and a string. strcpy doesn't give the required output as i believe it overwrites the value in first array from the second. i need to do something like this in C++ (this what i do in java)

seat=seat+tempGuest.toString()+". " //Java

strcat_s(p, 150,seating[i][j].toString());

this gives an error as seating[i][j].tostring() returns a char* type.

this is my function code

char* Auditorium::toString(){


    char* p = new char[150];
    cout << "The current seating is\n";
    cout << "-------------------------\n";
    for (int i = 0; i < rowNum1; i++)
    {
        for (int j = 0; j < columnNum1; j++)
        {

            strcat_s(p, 150,seating[i][j].toString());
            strcat_s(p, 150," ");


        }
        strcat_s(p, 150,"\n");

    }
    return p;

}

seating[i][j].toString() is getting value from the following function

char* Guest::toString()
{

    char * p = new char[30];

    p[0] = firstName[0];
    p[1] = '.';
    p[2]=lastName[0];
    p[3] = '.';
    p[4] = '\0';
        return p;
}
khan
  • 9
  • 4
  • Can you not simply de-reference `seating[i][j]` ( and `p` ) ? – Ryan Turnbull Oct 03 '17 at 06:54
  • 1
    Please [edit] your question and add the declarations of all variables. And why do you use raw `char` pointers? In C++ you should rather use `std::string`. Also read this: [mcve]. – Jabberwocky Oct 03 '17 at 06:56
  • 1
    _this gives an error as seating[i][j].tostring() returns a char* type._ Which error? [edit] your question and paste the verbatim error message. – Jabberwocky Oct 03 '17 at 06:59
  • i need to return a char* value so making a new char* to store the returning values seemed appropriate – khan Oct 03 '17 at 06:59
  • @khan if you want a good answer please [edit] your question and put all necessary information _there_ as requested in previous comments. – Jabberwocky Oct 03 '17 at 07:00
  • @MichaelWalz my whole code is too big for me to post here. i just wanna know that how can i return all the value in a single string. seating[i][j].toString() returns something like this ?.?. so i need to store it so that i can show it as ?.?. ?.?. A.S. ?.?. S.K. ?.? hope you got my point – khan Oct 03 '17 at 07:04
  • @khan please post the error message you get. Statements such as _this gives an error_ are not really helpful – Jabberwocky Oct 03 '17 at 07:08
  • strcat_s(p, 150,seating[i][j].toString()); //Exception thrown (breakpoint triggered) – khan Oct 03 '17 at 07:17
  • The way you use `strcat_s` looks correct. The problem is most likely within the dereferencement of `seating[i][j]`. Put `printf ("%s\n", seating[i][j].toString());` before `strcat_s(p, 150,seating[i][j].toString());`, then you'll probably get the problem there. Learn how to use the Visual Studio debugger. – Jabberwocky Oct 03 '17 at 07:23
  • i was doing it with cout< – khan Oct 03 '17 at 07:28
  • So there must be some bug in the code you don't show. Learn how to use the debugger. I'm giving up here. – Jabberwocky Oct 03 '17 at 07:49
  • 1
    You are walking the wrong path. C++ automatically manages allocation and de-allocation when you use `std::string`, but you must consistently call `delete[]` on any array you allocate with `new[]` to avoid memory leaks. If you are a beginner do yourself a favour and stick to `std::string`, and if you want for learning purposes dig into raw allocation build a simplified [mcve] so that we can help you to fix the errors. – Serge Ballesta Oct 03 '17 at 07:49
  • Additionally, current code does leak memory but does not exhibit any error. The error is in currently not shown code, and is probably related to memory management – Serge Ballesta Oct 03 '17 at 08:43

2 Answers2

3

In C++, you use std::string. In this case you could even use a string stream:

#include <sstream>

std::string Auditorium::toString() {

    std::ostringstream oss;
    oss << "The current seating is\n";
    oss << "-------------------------\n";
    for (int i = 0; i < rowNum1; i++) {
        for (int j = 0; j < columnNum1; j++) {
            oss << seating[i][j].toString();
        }
        oss << "\n";
    }
    return oss.str();
}

Without the stream, consider:

std::string Auditorium::toString() {

    std::string result;
    for (int i = 0; i < rowNum1; i++) {
        for (int j = 0; j < columnNum1; j++) {
            result += seating[i][j].toString();
            result += ' ';
        }
        result += '\n';
    }
    return result;
}

BONUS

Even more in C++ style, don't provide a toString, but provide operator<<:

Live On Coliru

#include <ostream>
#include <string>
#include <array>

struct Guest {
    std::string firstName, lastName;

    friend std::ostream& operator<<(std::ostream& os, Guest const& g) {
        return os << g.firstName[0] << '.' << g.lastName[0] << '.';
    }
};

namespace {
    using Row = std::array<Guest, 12>;

    inline std::ostream& operator<<(std::ostream& os, Row const& row) {
        for (Guest const& guest : row)
            os << guest << " ";
        return os;
    }
}

struct Auditorium {
    std::array<Row, 10> seating;

    friend std::ostream& operator<<(std::ostream& os, Auditorium const& auditorium) {

        for (Row const& row : auditorium.seating)
            os << row << "\n";

        return os;
    }
};

#include <iostream>

int main() {
    Auditorium auditorium {
        Row {Guest {"Jacob","Lettsom"}, {"Brion","Peasee"}, {"Kelvin","Tomasoni"}, {"Marabel","Fere"}, {"Hertha","Bartlam"}, {"Devondra","Grahl"}, {"Ike","Annott"}, {"Patrick","Cheyenne"}, {"Eada","Dawe"}, {"Marget","Glashby"}, {"Henderson","Glaum"}, {"Cassie","Winsom"}},
        Row {Guest {"Pierson","Kitchen"}, {"Elisha","Pass"}, {"Shirline","Wigin"}, {"Lucas","Stanmore"}, {"Norri","Hitzschke"}, {"Mercedes","Blackboro"}, {"Nappie","Breche"}, {"Freda","Mitton"}, {"Neils","Adamou"}, {"Mack","Rannells"}, {"Gaspard","Christoffersen"}, {"Sherwin","Kenwell"}},
        Row {Guest {"Wallas","Chellam"}, {"Doralin","Corthes"}, {"Sebastien","Scoble"}, {"Domini","Sprott"}, {"Lazaro","Bunton"}, {"Hinda","Korn"}, {"Renata","Vogt"}, {"Delmar","MacDwyer"}, {"Violette","Villiers"}, {"Nicko","McDirmid"}, {"Susanetta","MacCaughey"}, {"Hillary","McNuff"}},
        Row {Guest {"Alex","Downie"}, {"Caro","Westrey"}, {"Burr","Kalkofer"}, {"Ruy","Shelmerdine"}, {"Winfield","Beri"}, {"Isacco","Ellwell"}, {"Gideon","Beaford"}, {"Simon","Blaylock"}, {"Willy","Kloser"}, {"Guillemette","Boult"}, {"Mariya","Oehme"}, {"Emory","Angless"}},
        Row {Guest {"Jammie","Klimek"}, {"Monro","Passman"}, {"Page","Kornes"}, {"Giorgio","Couttes"}, {"Alexine","Glayzer"}, {"Jeni","Ferschke"}, {"Rock","Farrants"}, {"Katrinka","Schnieder"}, {"Irina","Ault"}, {"Antonetta","Griss"}, {"Pammy","Bertenshaw"}, {"Erinna","Terbeck"}},
        Row {Guest {"Evania","Sympson"}, {"Randy","Colvin"}, {"Legra","Osinin"}, {"Michaeline","Moroney"}, {"Adiana","Westbrook"}, {"Kellsie","Smeeton"}, {"Rodrick","Russ"}, {"Winny","Eggleston"}, {"Odille","Jerosch"}, {"Stacee","Liepina"}, {"Lucila","Jedras"}, {"Selma","Perch"}},
        Row {Guest {"Lynda","Palmar"}, {"Gracie","Jennick"}, {"Cleveland","Mordue"}, {"Elias","Manssuer"}, {"Kimbra","Cicchitello"}, {"Genni","Woliter"}, {"Gale","Baudassi"}, {"Johann","Swindlehurst"}, {"Andrei","De" "Laspee"}, {"Edythe","Dorr"}, {"Janela","Fydo"}, {"Silvia","Suerz"}},
        Row {Guest {"Rachel","Shoutt"}, {"Germain","Strangward"}, {"Margot","Son"}, {"Electra","Wookey"}, {"Samuel","Tight"}, {"Brande","Cable"}, {"Ford","Aitken"}, {"Noll","Woolf"}, {"Jourdan","Morewood"}, {"Milo","Trimming"}, {"Adair","Peck"}, {"Darnall","Loftus"}},
        Row {Guest {"Dene","Creer"}, {"Leena","Autry"}, {"Dickie","Wiggington"}, {"Josephine","Eagan"}, {"Hetty","Yoodall"}, {"Gayla","Dibson"}, {"Elwood","Torri"}, {"Eunice","Scapelhorn"}, {"Everett","Bedingfield"}, {"Ralf","Lodeke"}, {"Steve","Dockreay"}, {"Rod","Bruford"}},
        Row {Guest {"Siouxie","Rayment"}, {"Sheila-kathryn","Neal"}, {"Land","Beggi"}, {"Carson","Ferriman"}, {"Aile","Nias"}, {"Paige","Juckes"}, {"Cazzie","Leadstone"}, {"Selinda","Parlet"}, {"Rayner","Kesby"}, {"Murvyn","Laming"}, {"Lorianna","Pardey"}, {"Joane","Sneesby"}},
    };

    std::cout << auditorium << "\n";
}

Prints

J.L. B.P. K.T. M.F. H.B. D.G. I.A. P.C. E.D. M.G. H.G. C.W. 
P.K. E.P. S.W. L.S. N.H. M.B. N.B. F.M. N.A. M.R. G.C. S.K. 
W.C. D.C. S.S. D.S. L.B. H.K. R.V. D.M. V.V. N.M. S.M. H.M. 
A.D. C.W. B.K. R.S. W.B. I.E. G.B. S.B. W.K. G.B. M.O. E.A. 
J.K. M.P. P.K. G.C. A.G. J.F. R.F. K.S. I.A. A.G. P.B. E.T. 
E.S. R.C. L.O. M.M. A.W. K.S. R.R. W.E. O.J. S.L. L.J. S.P. 
L.P. G.J. C.M. E.M. K.C. G.W. G.B. J.S. A.D. E.D. J.F. S.S. 
R.S. G.S. M.S. E.W. S.T. B.C. F.A. N.W. J.M. M.T. A.P. D.L. 
D.C. L.A. D.W. J.E. H.Y. G.D. E.T. E.S. E.B. R.L. S.D. R.B. 
S.R. S.N. L.B. C.F. A.N. P.J. C.L. S.P. R.K. M.L. L.P. J.S. 
sehe
  • 374,641
  • 47
  • 450
  • 633
  • @sp2danny oops :) – sehe Oct 03 '17 at 08:15
  • why that `` include appears right before `main()`? – vasek Oct 03 '17 at 08:19
  • @vasek it provides `std::cout` – sehe Oct 03 '17 at 08:19
  • @sehe sure but why it is not in the beginning of the file among the others? – vasek Oct 03 '17 at 08:20
  • @vasek no particular reason. I like this way because it shows people you can overload the operators without having `iostream`. See the rationale here: https://isocpp.org/wiki/faq/coding-standards#declare-near-first-use (related logic) I've fixed the headers a bit (wasn't using stringstream in the last example). – sehe Oct 03 '17 at 08:25
0

Using std::string is a better option, as per sehe's answer.

However, I would like to add, if you ever feel tempted to type new in C++, you are doing it wrong. Wrong as in gluing bird-feathers on a rocket, or putting horseshoes on a car. C++ is built around the idea of deterministic destruction, so if you want to 'grok' C++, first order of business is switching over to value-semantics and RAII

sp2danny
  • 7,488
  • 3
  • 31
  • 53