How do I combine two strings? - c++

The question requires combining two strings(the longer string in the front and the shorter one after the longer one) without using <string> header file.Each string inputted can't exceed 20 characters.
My logic behind this is:
first use strlen to get the length of the str1 and str2,
use str3 to store the longer string, and str4 to store the shorter.
add str3 and str4 to str5
Here is my code:
#include<iostream>
using namespace std;
int main()
{
// combine two strings , longer in the front, and shorter
// after it. do not use strcat
char str1[20],str2[20],str3[20],str4[20],str5[40];
// str1 and str2 stores original data, str3 stores longer
// and str4 stores shorter, str5 stores total
int j=0;
cin.getline(str1,20);
cin.getline(str2,20);
if(strlen(str1)<=strlen(str2))
// give longer string value to str3,shorter to str2
{
for (int i=0;i<20;i++)
{
str3[i]=str2[i];
str4[i]=str1[i];
}
}
else
{
for (int i=0;i<20;i++)
{
str3[i]=str1[i];
str4[i]=str2[i];
}
}
for(j=0;str3[j]!='\0';j++)
{
str5[j]=str3[j];
}
for(int i=j;i<40;i++)
for(int m=0;m<20;m++)
{
str5[i]=str4[m];
}
cout<<str5<<endl;
return 0;
}
Here is the ouput:
What's my problem here? What are those characters in between the two strings? Thank you!!

Especially since you explicitly mentioned being a beginner, the solution is to use std::string:
#include <iostream>
#include <string>
int main() {
std::string a;
getline(std::cin, a);
std::string b;
getline(std::cin, b);
// Ensure that the longer string goes to the front.
if (a.size() < b.size());
swap(a, b);
std::string result = a + b;
std::cout << result << '\n';
// Or, simply:
std::cout << a << b << '\n';
}
The message here is that C++, despite its quirks, is a very high level language if you rely on its library instead of implementing every low level operation from scratch.

Everything is fine (!) up to this point
for(int i=j;i<40;i++)
for(int m=0;m<20;m++) // This loop runs m=0 to 20 for each position of i
{
str5[i]=str4[m];
}
For each index i you are copying in all 20 elements from str4, leaving just the value at str4[19] which could be anything
Just increment i and m by one together
int m = 0;
for(int i=j;i<40;i++)
{
str5[i]=str4[m++];
}

You are copying the entire 20 characters, 40 characters in the loop into the variables. stop copying when you find a '\0' character.
But using the std::string will make life simpler :)

Using std::string is nice and all but here's a few tips for working with char*:
1) You shouldn't copy strings to separate shorter and longer string, just use pointers and then work with these pointers, something along these lines:
const char *longer_string = 0, *shorter_string = 0;
if(strlen(str1)<=strlen(str2))
{
shorter_string = str1;
longer_string = str2;
}
else
{
shorter_string = str2;
storter_string = str1;
}
2) Using strcpy and strcat to combine strings could make life a lot easier:
char *combined_string = new char [strlen (shorter_string) + strlen (longer_string) + 1];
strcpy (combined_string, longer_string);
strcat (combined_string, shorter_string);
Some compilers would say that these functions aren't safe and you have to stick to _s versions, but I guess it's entirely up to you.

Since this is obviously homework: I'll just point out the existence of the function strcat, and the fact that you can use char* to the arrays, and just swap them, without having to recopy anything between the initial read and the concatenation (which means that you only need two arrays: one for each of the inputs, and one for the final value).
And also, when calculating sizes, etc. do not forget that C style strings have an extra '\0' at the end, and make allowances for it.

As #David Sykes has pointed out, the problem is with your for loop. So when you read input from cin ,it is not necessary that your input string contains 20 character. But in you form loop you are looping through those string beyond their length which may contains garbage characters. Example
char str1[20]
cin.getline(str1,20);
cout << str1[19] << endl;
Suppose your input for above code is "ABCD" which contains only 4 characters but your array has capacity of 20. So the remaining space has junk characters and when you will try to print any thing beyond actual length you will get wild character as you are getting in your code.

Related

How to explain weird characters at the end of my char array, and the wrong result of using strlen function in my code

I am a complete beginner so the code may seem to be easy, but I cannot find a solution why it returns such values as:
input: kkkk
output:
14
kkkkřřřř╩┬ëŢ
Suprisingly the code works fine with online compilators, but not with the Visual Studio.
#include<iostream>
#include<string.h>
int main()
{
char word[20];
std::cin >> word;
int length = strlen(word);
int p = length - 1, i = 0;
char *var=new char [length];
while (i < length&&p>=0)
{
var[i]= word[p];
p--;
i++;
}
std::cout <<strlen(var)<<endl<< var;
if (!strcmp(var, word)) std::cout << "\nThe word is a palindrome";
return 0;
}
I can not use strings because my University doesn't allow to do so. I also know there are many different ways to attend to this problem but I just really want know what I have done wrong in this one :/
Your "copy routine" copies each character, but it does not copy the string termination character. Note that C-style strings as used in functions like strlen or strcmp need to be 0-terminated, and even cout <<, when getting a parameter of type char*, treats this as a C-style string: It will read until finding the terminating '\0', and if you do not write one, it will read beyond the boundaries you think it should do.
If your write
...
}
var[length] = '\0';
std::cout <<strlen(var)<<endl;
...
it should work.

how to put a string in a char stack and print it out? c++

I am passing a string to my function, and the function is supposed to use that string to put individual chars in a stack. Then the stack is supposed to spit it back out (Since it's a stack it should be reversed). For example if my string is hello, it should print "olleh". But instead I'm getting ooooo. I think it has something to do with the fact that I'm setting ch equal to a different character every time but I'm not sure how to input those character in a different way.
void Stack::function2reverse(string myString) {
int countItIt = 0;
int sizeOfString = myString.size();
char Ch ;
for (int i= 0; i< sizeOfString; x++)
{
Ch = myString[x];
stack.push(Ch);
countIt ++;
}
while (countIt != 0)
{
cout << Ch;
stack.pop();
countIt --;
}
}
cout << Ch; - you print the same character every time (the last one entered, so 'o').
Instead, print the top character in the stack: std::cout << stack.top().
std::stack keeps track of its own size, so you don't need to worry about that either. Then you can replace your print loop with:
while (!stack.empty()) {
std::cout << stack.top();
stack.pop();
}
And of course, the Standard Library provides a std::reverse function anyway, so if this was not just an exercise in learning about std::stack, you could use that (and I can think of several other things to do as well, depending on exactly what you are trying to achieve):
std::string s = "hello";
std::reverse(std::begin(s), std::end(s));
// s now contains "olleh"
You may also want to read up on why using namespace std; is a bad practice.

How to get length of a string using strlen function

I have following code that gets and prints a string.
#include<iostream>
#include<conio.h>
#include<string>
using namespace std;
int main()
{
string str;
cout << "Enter a string: ";
getline(cin, str);
cout << str;
getch();
return 0;
}
But how to count the number of characters in this string using strlen() function?
For C++ strings, there's no reason to use strlen. Just use string::length:
std::cout << str.length() << std::endl;
You should strongly prefer this to strlen(str.c_str()) for the following reasons:
Clarity: The length() (or size()) member functions unambiguously give back the length of the string. While it's possible to figure out what strlen(str.c_str()) does, it forces the reader to pause for a bit.
Efficiency: length() and size() run in time O(1), while strlen(str.c_str()) will take Θ(n) time to find the end of the string.
Style: It's good to prefer the C++ versions of functions to the C versions unless there's a specific reason to do so otherwise. This is why, for example, it's usually considered better to use std::sort over qsort or std::lower_bound over bsearch, unless some other factors come into play that would affect performance.
The only reason I could think of where strlen would be useful is if you had a C++-style string that had embedded null characters and you wanted to determine how many characters appeared before the first of them. (That's one way in which strlen differs from string::length; the former stops at a null terminator, and the latter counts all the characters in the string). But if that's the case, just use string::find:
size_t index = str.find(0);
if (index == str::npos) index = str.length();
std::cout << index << std::endl;
Function strlen shows the number of character before \0 and using it for std::string may report wrong length.
strlen(str.c_str()); // It may return wrong length.
In C++, a string can contain \0 within the characters but C-style-zero-terminated strings can not but at the end. If the std::string has a \0 before the last character then strlen reports a length less than the actual length.
Try to use .length() or .size(), I prefer second one since another standard containers have it.
str.size()
Use std::string::size or std::string::length (both are the same).
As you insist to use strlen, you can:
int size = strlen( str.c_str() );
note the usage of std::string::c_str, which returns const char*.
BUT strlen counts untill it hit \0 char and std::string can store such chars. In other words, strlen could sometimes lie for the size.
If you really, really want to use strlen(), then
cout << strlen(str.c_str()) << endl;
else the use of .length() is more in keeping with C++.
Manually:
int strlen(string s)
{
int len = 0;
while (s[len])
len++;
return len;
}
#include<iostream>
#include<conio.h>
#include<string.h>
using namespace std;
int main()
{
char str[80];
int i;
cout<<"\n enter string:";
cin.getline(str,80);
int n=strlen(str);
cout<<"\n lenght is:"<<n;
getch();
return 0;
}
This is the program if you want to use strlen .
Hope this helps!
Simply use
int len=str.length();

How can a conversion from string to char[] make it longer?

I have a problem I cannot really understand how it could exist.
I have a bunch of files ordered by time and containing a bunch of objects. The result should be one file per time ordered in a directory per object.
It works quite fine but at the point where I convert the Outputstring to a char[] to use fstream.open(), the array has 3 characters more than the string has.
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int main()
{
string strOutput;
char *OutputFile;
short z;
strOutput = "/home/.../2046001_2013-02-25T0959.txt";
cout << strOutput << endl;
OutputFile = new char[strOutput.length()];
z = 0;
while (z < strOutput.length())
{
OutputFile[z] = strOutput[z];
z++;
}
cout << OutputFile << endl;
return 0;
}
The first output is always correct but the second sometimes has the end .txt60A, .txt5.a or .txt9.A.
When it occurs its always the same object and time and it happens every try. But not every object does that.
For obvious reasons I cannot reproduce this error in this minimal code snippet, but I also don't want to post the whole 390 lines of code.
Do you have any suggestions?
You are missing terminating null at the end of C string. To fix:
OutputFile = new char[strOutput.length() + 1]; // notice +1
z = 0;
while (z < strOutput.length())
{
OutputFile[z] = strOutput[z];
z++;
}
OutputFile[z] = 0; // add terminating 0 byte
Of course there are better ways to do the whole thing... you don't really need to copy at all, just get rid of OutputFile and the whole loop, and use the char array inside std::string:
cout << strOutput.c_str() << endl;
I assume the real code wants a C string. std::cout can print std::string directly, of course:
cout << strOutput << endl;
If you actually want to create a copy, it's best to just copy std::string and store that, and use c_str-method to get the C buffer when you need it:
string OutputFile = strOutput;
If you know you really do need a raw char array allocated from heap, you should use std::unique_ptr (or possibly some other C++ smart pointer class) to wrap the pointer, so you do not need to delete manually and avoid memory leaks, and also use standard library function to do copying:
#include <memory>
#include <cstring>
...
unique_ptr<char[]> OutputFile(new char[strOutput.length() + 1];
::strcpy(OutputFile, strOutput.c_str()); // :: means top level namespace
Char arrays need an extra null character or \0 appended to the end, otherwise the code reading the string will run past the end of the array until it finds one.
OutputFile = new char[strOutput.length() + 1];
z = 0;
while (z < strOutput.length())
{
OutputFile[z] = strOutput[z];
z++;
}
OutputFile[z] = '\0';
It may appear to work if the next byte after the array happens to be a null, but that's just a coincidence. I'm sure that's why your code works on the first pass.
at the point where I convert the Outputstring to a char[] to use fstream.open()
You don't have to do that. Do something like this instead:
outfile.open(Outputstring.c_str(), std::fstream::out)
Of course, if you have a C++11-compliant compiler, you can just do:
outfile.open(Outputstring, std::fstream::out)

Append to the end of a Char array in C++

Is there a command that can append one array of char onto another? Something that would theoretically work like this:
//array1 has already been set to "The dog jumps "
//array2 has already been set to "over the log"
append(array2,array1);
cout << array1;
//would output "The dog jumps over the log";
This is a pretty easy function to make I would think, I am just surprised there isn't a built in command for it.
*Edit
I should have been more clear, I didn't mean changing the size of the array. If array1 was set to 50 characters, but was only using 10 of them, you would still have 40 characters to work with. I was thinking an automatic command that would essentially do:
//assuming array1 has 10 characters but was declared with 25 and array2 has 5 characters
int i=10;
int z=0;
do{
array1[i] = array2[z];
++i;
++z;
}while(array[z] != '\0');
I am pretty sure that syntax would work, or something similar.
If you are not allowed to use C++'s string class (which is terrible teaching C++ imho), a raw, safe array version would look something like this.
#include <cstring>
#include <iostream>
int main()
{
char array1[] ="The dog jumps ";
char array2[] = "over the log";
char * newArray = new char[std::strlen(array1)+std::strlen(array2)+1];
std::strcpy(newArray,array1);
std::strcat(newArray,array2);
std::cout << newArray << std::endl;
delete [] newArray;
return 0;
}
This assures you have enough space in the array you're doing the concatenation to, without assuming some predefined MAX_SIZE. The only requirement is that your strings are null-terminated, which is usually the case unless you're doing some weird fixed-size string hacking.
Edit, a safe version with the "enough buffer space" assumption:
#include <cstring>
#include <iostream>
int main()
{
const unsigned BUFFER_SIZE = 50;
char array1[BUFFER_SIZE];
std::strncpy(array1, "The dog jumps ", BUFFER_SIZE-1); //-1 for null-termination
char array2[] = "over the log";
std::strncat(array1,array2,BUFFER_SIZE-strlen(array1)-1); //-1 for null-termination
std::cout << array1 << std::endl;
return 0;
}
If your arrays are character arrays(which seems to be the case), You need a strcat().
Your destination array should have enough space to accommodate the appended data though.
In C++, You are much better off using std::string and then you can use std::string::append()
You should have enough space for array1 array and use something like strcat to contact array1 to array2:
char array1[BIG_ENOUGH];
char array2[X];
/* ...... */
/* check array bounds */
/* ...... */
strcat(array1, array2);
There's no built-in command for that because it's illegal. You can't modify the size of an array once declared.
What you're looking for is either std::vector to simulate a dynamic array, or better yet a std::string.
std::string first ("The dog jumps ");
std::string second ("over the log");
std::cout << first + second << std::endl;