-3

I need to append the value of string2 to string1 without using append method in string library. So far, I've only managed to do this:

#include<iostream>
#include<string>
using namespace std;
int main(){
    string s1="Messi ";
    string s2="best";
    int i=s1.size();
    int j=s2.size();
    int count;
    for(count=0;count<=j;count++){
        s1[i++]=s2[count];

    }   
    cout<<s1;
}

But this, only gives me the value of s1 which is "Messi ". However, I checked by doing this: s1[8]. Since, s1 has index 5, s1[8] shouldn't work, right? But, it does and I get "s" which is in s2. So, it means that the value of s2 is indeed going in s1 but somehow, typing s1 only shows "Messi".

The reason I ask this because we were given this set of instructions to implement the program(yes it appears to be used on c strings but we were told to implement on string object):

Step 1: Initialize i= strlen(s1)
Step 2: Initialize j=strlen(s2)
Step 3: Initialize count=0
Step 4: Repeat steps 5 to 7 while count<=j
Step 5: s1[i]=s2[count]
Step 6: i=i+1
Step 7: count=count+1
ohnope
  • 27
  • 8
  • I assume push_back is also out: [http://www.cplusplus.com/reference/string/string/push_back/](http://www.cplusplus.com/reference/string/string/push_back/) – drescherjm Jan 09 '20 at 21:30
  • 6
    Is `+=` also out? – NathanOliver Jan 09 '20 at 21:31
  • 1
    Would `resize` work? Ex: `s1.resize(i+j);` then do the loop. – 001 Jan 09 '20 at 21:32
  • What about allocating a new string of the size of both and combining them? – Rosme Jan 09 '20 at 21:34
  • actually, my instructor gave this task, so he explicitly stated don't use library append function. I suppose += is also out because he advised us to code it like this(in a loop and take the size of both strings like that etc) – ohnope Jan 09 '20 at 21:34
  • @Rosme you mean I declare s3 and give it the size of s1 and s2 combined? How do I do that? And how, then will I combine what's in s1 and s2? – ohnope Jan 09 '20 at 21:35
  • 1
    *suppose += is also out because he advised us to code it like this(in a loop and take the size of both strings like that etc* -- I guess your professor is into unsafe programming practices. All of that work on the programmer is just an invitation for bugs to happen. – PaulMcKenzie Jan 09 '20 at 21:43
  • @ohnope Your code causes an `assert()` dialog to appear when you run this under Visual Studio with the message `"string subscript out of range"`. So none of your observations would be observed. – PaulMcKenzie Jan 09 '20 at 21:46
  • 1
    Since `std::string` is a class, you cannot perform any operations on it without using the class member functions / operator overloads (and therefore the library) you need to be explicit about what subset you are allowed to use. Fore example in your attempt you have used the _library function `std::string::operator[]()`. From your comment it appears that you have been given more information than you have given in the question - you should place all relevant information in the question. – Clifford Jan 09 '20 at 21:49
  • @PaulMcKenzie oh ok.. I used it in DevC++ and it was giving that output there – ohnope Jan 09 '20 at 21:50
  • @ohnope -- There is a reason for the `assert` to occur. The answers given about going out-of-bounds is the reason. The debug version of Visual C++ has these checks. – PaulMcKenzie Jan 09 '20 at 21:52
  • The edit makes your question totally different. You are not supposed to use `std::string` - you are supposed to use `char[]` (C strings). – Ted Lyngmo Jan 09 '20 at 21:53
  • you're right. strlen is used on cstrings. But, he told us to implement this on string object – ohnope Jan 09 '20 at 21:55
  • I think he has misspoken, clearly the answer requires the use of C strings, and that is the only plausible implementation. I'd go with what is written rather then what may have said verbally. – Clifford Jan 09 '20 at 21:58
  • actually, he explicitly said it to be used on string objects. That's why. But, yeah I understand what you're saying. – ohnope Jan 09 '20 at 21:59
  • Why on earth he wants you to use a bad algorithm made for C string on `std::string`'s is beyond me. – Ted Lyngmo Jan 09 '20 at 21:59
  • Alright, thanks for helping out guys. And, may I know the reason for downvotes so I can word it properly? – ohnope Jan 09 '20 at 21:59
  • @Ted Lyngmo well, that's just how the institutes are here in pakistan – ohnope Jan 09 '20 at 22:00
  • Downvotes possibly because you have asked one question, then posted an image of an entirely different assignment. – Clifford Jan 09 '20 at 22:02
  • Put the complete algorithm in the question. At least we may then tell you if it's even possible to implement it with `std::string`s. It looks painful. – Ted Lyngmo Jan 09 '20 at 22:03
  • I did this because people kept asking me why I was doing this so I had to show that this was a task. Should I remove the pic? – ohnope Jan 09 '20 at 22:03
  • Plain text is always preferable to pictures so if you can manage to transcribe the complete algorithm that you are supposed to implement as text it'd be a better question – Ted Lyngmo Jan 09 '20 at 22:07
  • 1
    ok I've edited it – ohnope Jan 09 '20 at 22:11
  • I think people downvoted because the question is very unclear. You said that a subset of operations is allowed and another subset is not allowed. `std::string::append` is not allowed. `std::string::operator[]` and `std::string::size` are allowed. `std::string::operator+=` could be allowed but you are not sure. What is with `std::string::operator+`? Is it allowed? Step 5 of the given algorithm causes undefined behavior without resizing `s1`. – Thomas Sablik Jan 09 '20 at 22:18

3 Answers3

3

I think this is what you want

#include<iostream>
#include<string>
using namespace std;
int main(){
    string s1="string1 ";
    string s2="string2";
    int i=s1.size();
    int j=s2.size();
    s1.resize(i+j);

    for(int count=0;count<=j;count++){

        s1[count+i]=s2[count];

    }   
    cout<<s1;
}

After the modifications you've made, I think the code you are looking for is as follows

#include<iostream>
#include<cstring>
using namespace std;
int main(){
    char s1[10]="str1 ";
    char s2[]="str2";
    int i=strlen(s1);
    int j=strlen(s2);
    int count = 0;
    for(;count<=j;){
        s1[i]=s2[count];
        i=i+1;
        count=count+1;

    }   
    cout<<s1;
}
asmmo
  • 6,922
  • 1
  • 11
  • 25
  • [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – Ted Lyngmo Jan 10 '20 at 09:35
  • @anonymous it only prints the value of s1,it doesn't print concatenated value. – ohnope Jan 15 '20 at 17:59
  • @ohnope I tested it. it prints `str1 str2`. what is the code you tried exactly? – asmmo Jan 15 '20 at 18:24
  • @anonymous yeah sorry, it does. I was printing in the loop. Anyway, thanks a lot for helping – ohnope Jan 15 '20 at 18:30
0

std::string it's not meant to be used that way. Class allocates its storage sand operator[] cannot expand it, so string cannot become longer. Documented and guaranteed way to append s2 to s1 is

s1 += s2;

Then you shouldn't use std::string because doing that with it is undefined behavior.. Actually, provided length of those initial values, std::string allowed not to use dynamic memory and use class's storage and you have no way to know if it's so from user level of access. It's implementation details.

You have to resize() string before writing in it and hold on idea that size() of string as an index unlike length includes zero character. Resize can change type of storage and allocate storage needed to hold second string. max_size() returns actual amount characters string can store without reallocation.

Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42
  • oh. But, as I said when I wrote s1[8], it did give me 's' which was in s2. So, it means that the value is going there and space is being allocated, right? – ohnope Jan 09 '20 at 21:37
  • @ohnope Doing that would be undefined behaviour. Space is not being allocated. Chances are that your two string objects are placed next to eachother in memory and since they contain short strings, they may be short-string-optimized and you read from the memory of the second string. Still UB. – Ted Lyngmo Jan 09 '20 at 21:39
  • *So, it means that the value is going there and space is being allocated, right?* -- Wrong. Undefined behavior can do strange things. As a matter of fact, your code `assert()`'s when run using Visual C++ as soon as you access those out-of-bounds elements. – PaulMcKenzie Jan 09 '20 at 21:39
  • @ohnope zero character of first string. size() includes it. SO printing string doesn't work. – Swift - Friday Pie Jan 09 '20 at 21:40
  • oh ok.. So, you're saying that I shouldn't use this approach and use += or append function? – ohnope Jan 09 '20 at 21:47
  • @ohnope or `resize()` s1 first, and for loop's body should be `s1[count+i]=s2[count];` you have to copy every character. actually while() loop looks neater for this purpose. or range-based loop. – Swift - Friday Pie Jan 09 '20 at 21:49
  • @ohnope Yes `+=` would be the most obvious. Your approach in the question is not even an option since it causes Undefined Behaviour (anything can happen - anything). – Ted Lyngmo Jan 09 '20 at 21:49
  • oh okay. Thanks for helping, guys. – ohnope Jan 09 '20 at 21:54
  • @ohnope at very least, make use of such site as https://en.cppreference.com and links it references – Swift - Friday Pie Jan 09 '20 at 21:59
0

You can either use += operator or just use insert:

string s1 = "Messi ";
string s2 = "best";

s1.insert(s1.size(), s2);
cout << s1 << endl;
cout << s1[8] << endl; // s

Or with iterators:

s1.insert(s1.cend(), s2.cbegin(), s2.cend());
Itachi Uchiwa
  • 3,044
  • 12
  • 26