I want to write a program, to create a function that concatenates two strings to form a single string. However, my program is not returning any value.
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
char* my_str_cat( char* s1, char* s2, char* combined ){
for(int i = 0;i<strlen(s1);i++){
combined[i]=s1[i];
}
for (int j=0;j<strlen(s2);j++){
combined[strlen(s1)+j]=s2[j];
}
return combined;
}
int main(){
char s1[100];
char s2[100];
char** combined = new char*;
cout<<"Enter s1: "<<endl;
cin.getline(s1,100);
cout<<s1<<endl;
cout<<"Enter s2: "<<endl;
cin.getline(s2,100);
my_str_cat(s1,s2,*combined);
delete combined;
return 0;
}
This declaration
char** combined = new char*;
declares a pointer of the type char ** that points to an allocated memory for an object of the type char *.
Dereferencing this pointer in this call
my_str_cat(s1,s2,*combined);
passes an uninitialized pointer of the type char * to the function my_str_cat.
And within the function this uninitialized pointer is used to access a memory that results in undefined behavior.
You need to allocate a memory for a character array large enough to store two concatenated C strings forming a new C string.
You could allocate the memory within the function itself.
The function can look the following way as it is shown in the demonstrative program below.
#include <iostream>
#include <iomanip>
#include <cstring>
char * my_str_cat( const char *s1, const char *s2 )
{
size_t n1 = std::strlen( s1 );
char * result = new char[n1 + std::strlen( s2 ) + 1];
std::strcpy( std::strcpy( result, s1 ) + n1, s2 );
return result;
}
int main()
{
const size_t N = 100;
char s1[N];
char s2[N];
std::cout << "Enter s1: ";
std::cin.getline( s1, sizeof( s1 ) );
std::cout << "Enter s2: ";
std::cout << std::noskipws;
std::cin.getline( s2, sizeof( s2 ) );
char *combined = my_str_cat( s1, s2 );
std::cout << combined << '\n';
delete []combined;
return 0;
}
The program output might look like
Enter s1: Hello
Enter s2: World!
Hello World!
Another approach of declaring and defining the function is when it is the user of the function that is responsible to supply the result character array to the function that will contain two concatenated strings.
For example
#include <iostream>
#include <iomanip>
#include <cstring>
char * my_str_cat( char *result, const char *s1, const char *s2 )
{
return std::strcat( std::strcpy( result, s1 ) , s2 );
}
int main()
{
const size_t N = 100;
char s1[N];
char s2[N];
std::cout << "Enter s1: ";
std::cin.getline( s1, sizeof( s1 ) );
std::cout << "Enter s2: ";
std::cout << std::noskipws;
std::cin.getline( s2, sizeof( s2 ) );
char *combined = new char[std::strlen( s1 ) + std::strlen( s2 ) + 1];
std::cout << my_str_cat( combined, s1, s2 ) << '\n';
delete []combined;
return 0;
}
The program output might look the same way as it is shown for the previous demonstrative program that is
Enter s1: Hello
Enter s2: World!
Hello World!
Without using standard string functions and using only loops the function can be defined the following way.
char * my_str_cat( char *result, const char *s1, const char *s2 )
{
char *p = result;
while ( *s1 ) *p++ = *s1++;
while ( ( *p++ = *s2++ ) );
return result;
}
First thing first, it (would) return a value its, just not assigned to anything. to do so:
*combined = my_str_cat(s1,s2,*combined);
Also either pass combined by refrence, or dont pass it al all.
But it doesnt cause it crashes with a seg fault, because you refere to s1[i] while s1 is not initialized.
Im gonna correct that in C style cause your code is really just C with spice:
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
using namespace std;
void my_str_cat( char* s1, char* s2, char* &combined){
int len = strlen(s1);
combined = (char*)calloc(1, (len + strlen(s2)));
strcpy(combined, s1);
strcpy(combined + len, s2);
}
int main(){
char s1[100];
char s2[100];
char* combined;
cout<<"Enter s1: " << endl;
cin.getline(s1,100);
cout<<s1<<endl;
cout<<"Enter s2: " << endl;
cin.getline(s2,100);
my_str_cat(s1,s2, combined);
cout << combined << endl;
delete combined;
return 0;
}
(Tho this works, i had i feeling of missing something while writting this. Please let me know what is it if you know.)
Related
Some languages have easy ways of doing this, but my question revolves in C and C++.
I wanna do something like this in Java:
public class sandbox {
public static void main(String[] args) {
System.out.println("Thank" + " you!");
}
}
And transfer it in C:
#include <stdio.h>
int main() {
/* The easiest way is like this:
char *text1 = "Thank";
char *text2 = " you";
printf("%s%s\n", text1, text2);
*/
printf("Thank" + " you."); // What I really want to do
}
How do I concatenate strings in a language like this?
You use just nothing:
puts ("Thank" " you.");
Concatenating strings is not that easy in C unfortunately, here's how to do it most succinctly:
char *text1 = "Thank";
char *text2 = " you";
char *text_concat = malloc(strlen(text1) + strlen(text2) + 1);
assert(text_concat);
text_concat = strcpy(text_concat, text1);
text_concat = strcat(text_concat, text2);
printf("%s\n", text_concat);
free(text_concat);
What I have understood from your question, hope the below solution will answer your question.
#include <stdio.h>
int main() {
char s1[100] = "Thank ", s2[] = "You";
int length, j;
// store length of s1 in the length variable
length = 0;
while (s1[length] != '\0') {
++length;
}
// concatenate s2 to s1
for (j = 0; s2[j] != '\0'; ++j, ++length) {
s1[length] = s2[j];
}
// terminating the s1 string
s1[length] = '\0';
printf("After concatenation: %s",s1);
return 0;
}
In C++, you can easily concatenate two string it by adding two string with a + operator.
#include <iostream>
using namespace std;
int main()
{
string s1, s2, result;
cout << "Enter string s1: ";
cin>>s1;
cout << "Enter string s2: ";
cin>>s2;
result = s1 + s2;
cout << "After concatenation: = "<< result;
return 0;
}
This is a concatenation, but is a constant or compile time concatenation, you can't concatenate strings like that, but in case you need to split a string constant in multiple parts is ok:
...
printf("Thank" " you."); // What I really want to do
...
For dynamic, runtime concatenation you need strcat like
strcat(text1, text2);
First you must assure that you have enough memory in target string, see this link http://www.cplusplus.com/reference/cstring/strcat/
Ok, that was the C way, but C++ has STL with std::string
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str1 = "hello ", str2 = "world";
cout<< str1 + str2<< endl;
return 0;
}
It is not possible in C to do something like printf("Thank" + " you."); because C doesn't support Operator Overloading Unlike C++. You can refer Is it possible to overload operators in C?
Redoing my previous question since I didn't provide enough detail.
I have a char pointer array, char* token[100]. Let's say I have a double-digit number, like 33.
How do I assign this int into an index in the token array, so that when I print out that token it will give me 33 and not some sort of ASCII value?
char* token[100];
int num = 33;
//How do I assign num into a specific token index, like for example:
token[1] = num;
//When I print out that token index, I want 33 to be printed out
cout << token[1] << endl; // I want to have 33 be the result. Right now I have '!' as an output
It seems you mean something like the following
#include <iostream>
#include <string>
#include <cstring>
int main()
{
char * token[100] = {};
int num = 33;
std::string s= std::to_string( num );
token[1] = new char[s.size() + 1];
std::strcpy( token[1], s.c_str() );
std::cout << "token[1] = " << token[1] << '\n';
delete [] token[1];
return 0;
}
The program output is
token[1] = 33
If you are not allowed to use C++ containers and functions then the program can look the following way
#include <iostream>
#include <cstdio>
#include <cstring>
int main()
{
char * token[100] = {};
int num = 33;
char buffer[12];
std::sprintf( buffer, "%d", num );
token[1] = new char[std::strlen( buffer ) + 1];
std::strcpy( token[1], buffer );
std::cout << "token[1] = " << token[1] << '\n';
delete [] token[1];
return 0;
}
I'm convinced, from comments, that you want an array of integer types. If we get further clarification about why this needs to be a char array, I'll update my answer, but from all available information it seems like you really want an integer-type array.
#include <iostream>
int main(int argc, char** argv)
{
int token[100] = {};
int num = 33;
token[1] = num;
std::cout << token[1] << std::endl;
return 0;
}
I want to take input from user in
char input[200];
Then I want to swap each character of that input according to
a='y'; b='b'; c='j'; d='m'; e='x'; f='f'; g='w'; h='i';
i='v'; j='c'; k='l'; l='u'; m='t'; n='a'; o='k'; p='h';
q='d'; r='p'; s='s'; t='n'; u='z'; v='q'; w='e'; x='r';
y='o'; z='g';
For example if the input is
hello
The output will be
ixuuk
I want to code in C++ using for loops and arrays.
I suggest you use a lookup array:
char output = conversion[input_char];
You can simplify the array to 26 letters by using some arithmetic:
char output = conversion[input_char - 'a'];
The expression input_char - 'a' makes the letter a refer to the first slot in the conversion array.
Here's an example of the array:
static const char conversion[] =
{'b', 'y', 'c', 'k', 'f', /*...*/, 'a'};
Using the above code, if input is a, the output will be b. For input of b, the output will be y, and so on.
No need to swap. Remember that swapping changes values. I believe you want conversion or translation instead.
Here is a demonstrative program that shows how it could be done
#include <iostream>
#include <cstring>
#include <utility>
int main()
{
std::pair<const char *, const char *> cipher =
{
"abcdefghijklmnopqrstuvwxyz",
"ybjmxfwivclutakhdpsnzqerog"
};
const size_t N = 200;
char input[N];
input[0] = '\0';
std::cin.getline( input, sizeof( input ) );
std::cout << '\"' << input << '\"' << std::endl;
for ( char *p = input; *p; ++p )
{
if ( const char *q = std::strchr( cipher.first, *p ) )
{
*p = cipher.second[q - cipher.first];
}
}
std::cout << '\"' << input << '\"' << std::endl;
return 0;
}
The program output is
"Hello"
"Hxuuk"
You could also use functions tolower or toupper to convert initially characters of the source string to some case.
Solved the problem
#include <iostream>
#include <cstring>
#include <utility>
int main()
{
std::pair<const char *, const char *>
cipher ("abcdefghijklmnopqrstuvwxyz",
"ybjmxfwivclutakhdpsnzqerog");
const size_t N = 200;
char input[N];
input[0] = '\0';
std::cin.getline( input, sizeof( input ) );
std::cout << '\"' << input << '\"' << std::endl;
for ( char *p = input; *p; ++p )
{
if ( const char *q = std::strchr( cipher.first, *p ) )
{
*p = cipher.second[q - cipher.first];
}
}
std::cout << '\"' << input << '\"' << std::endl;
return 0;
}
Special thanks to #Vlad from Moscow
i suggest you use the nested loop.
create an array of strings having all the alphabets.
then create another array of strings having all the characters you want to change with the alphabets in the same order of the alphabets.
#include <iostream>
using namespace std;
int main()
{
string alphabets="abcdefghijklmnopqrstuvwxyz" ,
cipher="ybjmxfwivclutakhdpsnzqerog" , word , newword="" ;
cin>>word;
newword=word;
for(int i=0;i<26;i++)
{
for(int j=0;j<26;j++)
{
if(word[i]==alphabets[j])
{
newword[i]=cipher[j];
break;
}
}
}
cout<<newword;
return 0;
}
I would like to copy reversed char* to the another char*. I miss one letter in the second line of the output.
I did:
#include <iostream>
using namespace std;
void cp(char *str2, char *str1){
char *pom1 = str1;
while(*pom1){
pom1++;
}
char* pom2 = str2;
while(*pom1 != *str1){
pom1--;
*pom2 = *pom1;
pom2++;
}
*pom2 = '\0';
}
int main()
{
char *str1 = "ppC", str2[10] = "Witaj";
cout << "Napis str2 "<< str2 << endl;
cp(str2,str1);
cout << "Napis str2 "<< str2 << endl;
cp(str2,"CJP");
cout << "Napis str2 "<< str2 << endl;
return 0;
}
and the output is:
Napis str2 Witaj
Napis str2 Cp
Napis str2 PJC
While it should be:
Napis str2 Witaj
Napis str2 Cpp
Napis str2 PJC
The bug is in this statement of the function
while(*pom1 != *str1){
There must be
while( pom1 != str1){
Take into account that string literals have type of constant arrays. So for example variable str1 has to be declared as
const char *str1 = "ppC";
Also the function should be declared as
void cp( char *str2, const char *str1 );
Also It will be useful to know that there is standard algorithm std::reverse_copy declared in header <algorithm>:)
There's reverse_copy in the stdlib
... and that it's used like:
template <typename CharT, size_t Ndest>
void cp(CharT (&dest)[Ndest], CharT const *src){
auto f = src, l = src + std::strlen(src);
assert(std::distance(f,l) < Ndest);
*(std::reverse_copy(f, l, dest)) = '\0';
}
So, see it Live On Coliru
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cassert>
template <typename CharT, size_t Ndest>
void cp(CharT (&dest)[Ndest], CharT const *src){
auto f = src, l = src + std::strlen(src);
assert(std::distance(f,l) < Ndest);
*(std::reverse_copy(f, l, dest)) = '\0';
}
#include <iostream>
int main()
{
char str1[] = "ppC";
char str2[10] = "Witaj";
std::cout << "Napis str2 "<< str2 << std::endl;
cp(str2, str1);
std::cout << "Napis str2 "<< str2 << std::endl;
cp(str2,"CJP");
std::cout << "Napis str2 "<< str2 << std::endl;
return 0;
}
Just use the Standard Library, std::reverse_copy() in this case:
std::reverse_copy( input , input + strlen( input ) , output );
copy paste solution
int len(const char *p) {
int c = 0;
while (*p != '\0')
{
c++;
p++;
}
return(c);
}
void cp(char *str2, const char *str1){
if(!(len(str2)<len(str1))){
const char *pom1 = str1;
while(*pom1){
pom1++;
}
char* pom2 = str2;
while( pom1 != str1){
pom1--;
*pom2 = *pom1;
pom2++;
}
*pom2 = '\0';
}
}
#include<iostream>
#include<string>
using namespace std;
void reverse(char* str)
{
char *new_str = str;
while(*new_str != '\n'){
new_str++;
}
while(new_str != str){
cout << *new_str;
new_str--;
}
cout << *new_str;
}
int main()
{
char *str = new char[1024];
str = "hello world";
reverse(str);
}
When I try to run this I get some crazy output and my computer starts to beep. What am I doing blatantly wrong here?
The end of a C string is marked by the character '\0'. You used '\n' which is the newline character.
You mean apart from using the naked leaky new, the deprecated char* instead of const char* or even better std::string, not using a Standard Library algorithm std::reverse, mixing IO with your algorithm and including the entire namespace std (which might indirectly bring std::reverse() into scope) without putting your own reverse() inside its own namespace?
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
// using namespace std; // for the brave, and drop the std:: in the next 3 lines
int main()
{
std::string str = "hello world"; // std::string instead of char*
std::reverse(begin(str), end(str)); // standard library algorithm
std::cout << str; // IO separate from algorithm
}
If you are only interested in how to code a reverse algorithm, here is one way to do it without relying on the fact that you have a null terminator:
template<class BidirIt>
void reverse(BidirIt first, BidirIt last)
{
while ((first != last) && (first != --last)) {
std::swap(*first++, *last);
}
}
The problem is that at first you assigned str the address of allocated memory and then reassigned it to point to string literal that has type const char[] in C++.
char *str = new char[1024];
str = "hello world";
This string literal has terminating zero char '\0'. It has no the new line char '\n'. So the function is invalid because it will try to access memory beyond the array searching the new line char.
The valid code could look the following way
#include <iostream>
using namespace std;
void reverse( const char* s )
{
const char *p = s;
while ( *p ) p++;
while ( p != s ) cout << *--p;
}
int main()
{
const char *s = "hello world";
reverse( s );
}
Or if you want to enter a string yourself interactively then main could look as
int main()
{
const size_t N = 1024;
char s[N];
cout << "Enter a statement: ";
cin.getline( s, N );
reverse( s );
}
correct your function :
void reverse(char* str)
{
char *new_str = str;
while(*new_str){ // use this instead of *new_ptr != '\n'
new_str++;
}
while(new_str != str){
cout << *new_str;
new_str--;
}
cout << *new_str;
}