I want to add string elements successively, for example st[]="morty", and I want to repeat its elements for example seven times. It should be st[]="mortymo". I wrote a function which is at below. (The length function is strlen).
void repeat(char* st,int n){
int i,k=0,l=length(st);
char* ptr;
ptr=(char*)malloc((n+1)*sizeof(char));
for (i=0;i<n;i++){
*(ptr+i)=*(st+k);
k++;
if(k==l)k=0;
}
}
The program below repeats characters from the original string.
Comments in the code:
#include<stdio.h>
#include<stdlib.h>
char* repeat(const char* st, size_t n){
// use `const` to note that pointer `st` will not be modified
// for purity you may want to use type `size_t` since returning type of strlen is `size_t`
size_t i, k=0;
size_t l = strlen(st);
// do not use (char *) cast
char* ptr = malloc((n+1)*sizeof(char)); // allocate enough room for characters + NULL
for (i=0; i< n; i++)
{
ptr[i] = st[k]; // use index for readability
k++;
if (k == l)
k=0;
}
ptr[i] = 0; // terminate the string
return ptr;
}
int main( )
{
char *str = "12345";
str = repeat(str, 15);
printf("%s\n",str);
free (str); // free the allocated memory inside the repeat function
return 0;
}
OUTPUT:
123451234512345
In your repeat function, you allocated ptr to hold the repeated string, but you didn't return or assign it to st. You can modify your repeat function as follows:
char* repeat(char* st,int n){
int i,k=0,l=strlen(st);
char* ptr;
ptr=(char*)malloc((n+1)*sizeof(char));
for (i=0;i<n;i++){
*(ptr+i)=*(st+k);
k++;
if(k==l)k=0;
}
*(ptr+n) = '\0';
return ptr;
}
/* some code*/
char *st = "morty";
st = repeat(st, 7);
Such that you are storing the result of the repeated string in st after.
If I have understood the assignment correctly then you need a function like that one shown in the demonstrative program.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char * repeat( const char *s, size_t n )
{
char *p = NULL;
size_t len = strlen( s );
if ( len == 0 ) n = 0;
p = ( char * )malloc( n + 1 );
if ( p )
{
size_t i = 0;
for ( size_t j = 0; i < n; i++ )
{
p[i] = s[j];
if ( ++j == len ) j = 0;
}
p[i] = '\0';
}
return p;
}
int main(void)
{
char *s = "Hi, Zusaetlich.";
char *p = repeat( s, 2 * strlen( s ) );
puts( p );
free( p );
return 0;
}
The program output is
Hi, Zusaetlich.Hi, Zusaetlich.
Pay attention to that the function is designed such a way that if the original string is empty then the resulted string is also empty because there is nothing to repeat.
As for your function then it has at least a memory leak because the memory allocated in the function is not freed.
Also as the original string is not changed then the corresponding parameter should be qualified with the const specifier. And the second parameter should have type size_t because at least the function strlen has the return type size_t.
So the function should be declared as it is shown in the demonstrative program.
Since you don't intend to modify the contents of st, go ahead and declare it as const. Since you intend to allocate a new string in your function, you should return it to the caller.
char *repeat(const char* st,int n){
k is unnecessary for your problem. Call the standard functions.
int i,l=strlen(st);
char* ptr;
Don't cast the result of malloc, as this can mask a fatal error in C. sizeof(char) is always 1. Check the result of the malloc call for success.
ptr=malloc(n+1);
if (ptr == NULL) return NULL;
for (i=0;i<n;i++){
Access arrays idiomatically with []. Note that k increments whenever i does, but you are applying a modulo operation of k. However, C has a modulo operator, which you can use directly on i.
ptr[i]=st[i%l];
}
Make sure the new string is NUL terminated. Your function is declared to return a result, but your implementation fails to do so.
ptr[n] = '\0';
return ptr;
}
C has many functions you can call to do the copying for you rather than the byte by byte loop you have written. There is simplicity in your implementation, but below is an alternative, that also includes additional error checking that is lacking in your solution.
(Some may balk at the use of sprintf, but it is being used correctly.)
char *
repeat (const char *st, int n) {
int l = st ? strlen(st) : 0;
char *ret = (st && n > 0 ? malloc(n+1) : 0), *p = ret;
while (ret && n > 0) {
p += sprintf(p, "%.*s", (l < n ? l : n), st);
n -= l;
}
return ret ? ret : "(nil)";
}
Try it online!
Related
I have done a code to solve the Sum String as Numbers problem on CodeWars.
On my machine it runs and returns the correct value, it also passes all tests on CodeWars, but for some reasons it's raised the Caught unexpected signal: 6 and free(): invalid pointer.
I have checked other questions related to this and other forums but it seems that i don't anything form there. I have used only size_t my pointer don't increase like a++ or anything in order to free to not be able to dealocate memory.
My code consists on:
a function char *to_num(const char *a,size_t *size) which converts all digits from ASCII to numbers (i.e. '3' => 3) and returns a char* to a dynamic allocated array with all that numbers. Also it removes all prefixed zeros.
void no_zeros(char *a) which simply deletes all the 0 from the start of a string (i.e. "0012" => "12")
a custom len function, because i use a different nul character, as my 0 in array is tehnically 0 digit. On this example i use 10 as terminating character
char *fill(char* a,size_t size) that returns a string prefixed with as many zeros as needed to reach the length size (i.e. for a="12" and size=4 it returns 0012)
and finnaly the main function char *strsum(const char *a, const char *b) which returns the sum written as a string (i.e. "123" + "456" returns "579")
The flow of this program goes like:
convert the strings received as parameter to numbers with to_num
if one number is longer than another the fill function is called to complet the smaller one so that we can perform the addition
than we perform the addition per components and return the number as string
I have a bug that prefixes my result with zero so i call the no_zeros on resut.
My code
#include <stdio.h>
#include <malloc.h>
#include <string.h>
void display(const char *a,size_t size){
for(size_t i=0;a[i]!=0 && i<size;i++){
if(a[i]>'0'){
printf("%c",a[i]);
}
else{
printf("%d",a[i]);
}
}
printf("\n");
}
char *to_num(const char *a,size_t *size){
size_t i=0,j=0;
*size = strlen(a);
char *result = malloc((*size+1)*sizeof(char));
if(result==NULL){return 0;}
while(a[i]=='0'){i++;}
while(a[i]!=0){
result[j] = a[i];
i++;
j++;
}
result[j]=0;
*size = j;
for(size_t i=0;i<*size;i++){
result[i] = result[i]-'0';
}
result[*size] =10;
return result;
}
void no_zeros(char *a){
size_t i=0,j=0;
while(a[i]=='0'){i++;}
while(a[i]!=0){
a[j] = a[i];
i++;
j++;
}
a[j]=0;
}
size_t len(char *a){
size_t s=0;
for(size_t i=0;a[i]!=10;i++){
s++;
}
return s;
}
char *fill(char* a,size_t size){
size_t a_size = len(a);
char *copy = malloc((size+2)*sizeof(char));
if(copy==NULL){return 0;}
for(size_t i=0;i<size-a_size;i++){
copy[i] = 0;
}
for(size_t i=0;i<a_size;i++){
copy[i+size-a_size] = a[i];
}
copy[size] = 0;
for(size_t i=0;i<size;i++){
}
return copy;
}
char *strsum(const char *a, const char *b)
{
size_t size_a,size_b,bigger,smaller;
char *x,*y;
x = to_num(a,&size_a);
y = to_num(b,&size_b);
bigger = size_a>=size_b ? size_a : size_b;
smaller = size_a<=size_b ? size_a : size_b;
if(bigger != smaller){
if(bigger == size_a){
y = fill(y,bigger);
size_b = bigger;
}
else{
x = fill(x,bigger);
size_a = bigger;
}
}
char *result = malloc((bigger+2)*sizeof(char));
if(result==NULL){return 0;}
int carry=0;
size_t i;
for(i=bigger;i>=0;i--){
result[i] = (x[i-1]+y[i-1]+carry)%10+'0';
carry = (x[i-1]+y[i-1]+carry)/10;
if(i==0) break;
}
result[bigger+1]=0;
no_zeros(result);
if(result[0]==0){return "0";}
free(x);
free(y);
return result;
}
int main(){
printf("%s\n",strsum("9567","800"));
}
display(): for(size_t i=0;a[i]!=0 && i<size;i++){: swap the order of the conditions so you do the boundary check before a[i].
strsum(): for(i=bigger;i>=0;i--){ doesn't make sense as i is a size_t i.e. unsigned and in the loop body you do x[i-1] and y[i-1] which is wrong when i is 0. What about this?
for(i=bigger; i; i--){
result[i] = (x[i-1]+y[i-1]+carry)%10+'0';
carry = (x[i-1]+y[i-1]+carry)/10;
}
result[0] = carry + '0';
strsum(): x and y leak as you free them after a return:
free(x);
free(y);
if(result[0]==0){return "0";}
strsum(): to_num() allocates an array and then fill() allocates a copy (2 mallocs) and in strsum() you may leak the first malloc() for either x or y:
x = to_num(a,&size_a);
y = to_num(b,&size_b);
// ...
if(bigger != smaller){
if(bigger == size_a){
y = fill(y,bigger);
size_b = bigger;
}
else{
x = fill(x,bigger);
size_a = bigger;
}
}
Either realloc() in fill() instead of creating a copy or use a temporary variable in strsum() so you can free the original malloc'ed value:
if(bigger != smaller){
if(bigger == size_a){
char *tmp = fill(y, bigger);
free(y);
y = tmp;
size_b = bigger;
}
else{
char *tmp = fill(x, bigger);
free(x);
x = tmp;
size_a = bigger;
}
}
Btw, this is the same code in both branches so consider writing a function.
main(): leaks the returned string:
int main(){
char *s = strsum("9567","800");
printf("%s\n", s);
free(s);
}
strsum(): Once you fix above mention leak in main() you can no longer do return "0". You would need a size check and possible realloc() before doing:
return strcpy(result, "0");
or you could free(result); return strdup("0");. This is most likely the root cause (in calling test code you don't see).
I'm trying to solve a piece of code a friend sent me. He's practicing pointers and is trying to reverse a string using them.
It should be a pretty simple task, but there's just a gap in my knowledge here. I've been able to successfully create a for loops which iterates through the string properly using i and j as control variables. I've been able to print out the characters as well, which need to be swapped.
The only problem is that commented line of code in the for loop. It's supposed to be swapping the two values, but is throwing an error, and I don't get why.
#include <stdio.h>
int length(char *p);
void reverse(char *);
int main() {
char *p = "Computer";
reverse(p);
}
int length(char *p) {
int i;
for (i = 0; *(p + i) != '\0'; i++);
return i;
}
void reverse(char *p) {
int l, i;
char t;
for (l = 0; *(p + l) != '\0'; l++);
int len = l;
int temp;
for (i = 0; i < l; i++, l--) {
t = *(p + i);
printf("i-th element - %c\n", t);
printf("j-th element - %c\n", *(p + len - 1 - i));
*(p + i) = *(p + len - 1 - i); // crash
}
puts(p);
}
I'm not even sure it's possible to swap them this way. I would have gone with the t = p[i]; p[i] = p[i + 1]... approach. If anyone can correct and explain this and the pointer related drama, that would be great.
Firstly, you must not try to modify string literals.
You should use an (modifiable) array:
char p[] = "Computer";
instead of
char *p = "Computer";
Secondly, you will need
*(p + len - 1 - i) = t;
after
*(p + i) = *(p + len - 1 - i);
to complete the swapping.
For starters you may not change a string literal
char *p = "Computer";
any attempt to change a string literal result in undefined behavior.
So instead of the pointer to a string literal declare a character array like
char s[] = "Computer";
Moreover your function reverse does not use the function length and in fact does not reverse a string.
This loop
for (i = 0; i < l; i++, l--) {
uses two auxiliary variables as indices.
The function reverse shall output nothing. What it shall do is one thing to reverse the passed string. It is the caller of the function that decides whether to output the reversed string or to use it for other purposes.
The functions length and reverse can be declared and defined using only pointers the following way
size_t length( const char *s )
{
const char *p = s;
while ( *p ) ++p;
return p - s;
}
and
char * reverse( char *s )
{
if ( *s )
{
for ( char *p = s, *q = s + length( s ); p < --q; ++p )
{
char c = *p;
*p = *q;
*q = c;
}
}
return s;
}
The function reverse can be called like
int main( void )
{
char s[] = "Computer";
puts( s );
puts( reverse( s ) );
}
Here is a demonstrative program.
#include <stdio.h>
size_t length( const char *s )
{
const char *p = s;
while ( *p ) ++p;
return p - s;
}
char * reverse( char *s )
{
if ( *s )
{
for ( char *p = s, *q = s + length( s ); p < --q; ++p )
{
char c = *p;
*p = *q;
*q = c;
}
}
return s;
}
int main( void )
{
char s[] = "Computer";
puts( s );
puts( reverse( s ) );
}
Its output is
Computer
retupmoC
As you can see in the both functions neither variable used as an index is present. The functions use only pointers.
Using pointes requires some care otherwise you'll get "Segmentation fault" everywhere. But let's do this. A technique to reverse the string I use, is first position one ponter to the beginning of string, and another pointer to the end of string; and promote the swap while they reach the middle of string (this way I cut the processing to a half) check this code
/* reverses a string
* !!! this function modifies input string !!!
*/
char *reverse(char *s)
{
char *h, *t, c; /* h)ead, t)ail and a temporary c */
int len = 0;
/* positioning the pointers at beginning and end of string s */
len = length(s);
h = (char*)&s[0];
t = (char*)&s[len - 1];
for (int i = 0; i < (len / 2); i++)
{
/* swap chars */
c = *h;
*h = *t;
*t = c;
/* increase h pointer, decrease t pointer */
h++;
t--;
}
return s;
}
Pure pointers... in anyform when swapping the *h and *t you can't get away from a temporary storage ( c );
Be aware the input string needs to be declared as char name[] otherwhise sigsegv follows you!
If you want to save the string for later vice printing it directly to stdout, you can do this:
char * reverse(char * I){
int i,l;
char * O;
l=strlen(I);
O=malloc(l+1);
for(i=1;i<=l;i++)O[i-1]=I[l-i];
O[l]='\0';
return O;
}
int main(){
char * p=reverse("Computer");
printf("%s",p);
free(p);
}
Trying to write a C program to reverse the given string (using Pointer) and here is the code.
[sample.c]
#include <stdio.h>
#include <stdlib.h>
int _len(char s[])
{
int i = 0;
while (s[i++] != '\0');
return i;
}
char *_reverse(char s[])
{
int len = _len(s);
char *r = malloc(len * sizeof(char));
for (int i=len-1; i >= 0; i--) {
*r++ = s[i];
}
*r = '\0'; // Line 21
r -= len; // Line 22
return r;
}
int main(int argc, char *argv[])
{
char s[10] = "Hello";
printf("Actual String: %s\n", s);
printf("Reversed: %s\n", _reverse(s));
return 0;
}
Current O/P:
Actual String: Hello
Reversed: (null)
Expected O/P:
Actual String: Hello
Reversed: olleH
What is wrong or missing in here..? Please correct me. Thanks in advance.
You are modifying the pointer "r" of your newly allocated memory. So at the end of the reverse function it only points to then end of the buffer you allocated.
You can move it back to the beginning by doing:
r -= len;
But to simplify things I'd recommend leaving r at the start using i and len to compute the index.
Also, you don't terminate the reversed string with a '\0'.
You increase r in the loop, then return it. Obviously, it points to an address after the actual reversed string. Copy r to another variable after malloc and return that.
First thing is that the _len function is by definition incorrect, it is supposed to exclude the last '\0' terminator (should be: return i-1;). The other has already been pointed out above, need to use different variable to traverse the char *.
#include <stdio.h>
#include <stdlib.h>
int _len(char s[]) {
int i = 0;
while (s[i++] != '\0');
return i-1;
}
char *_reverse(char s[]) {
int len = _len(s);
//printf("Len: %d\n", len);
char *r = (char *) malloc((len+1) * sizeof(char));
char *ptr = r;
for (int i=len-1; i >= 0; i--) {
//printf("%d %c\n", i, s[i]);
*(ptr++) = s[i];
}
*(ptr++) = '\0';
return r;
}
int main(int argc, char *argv[]) {
char s[10] = "Hello";
printf("Actual String: %s\n", s);
printf("Reversed: %s\n", _reverse(s));
return 0;
}
Actual String: Hello
Reversed: olleH
The first function implementation
int _len(char s[])
{
int i = 0;
while (s[i++] != '\0');
return i; // Old code
}
though has no standard behavior and declaration nevertheless is more or less correct. Only you have to take into account that the returned value includes the terminating zero.
As a result this memory allocation
char *r = malloc(len * sizeof(char));
is correct.
However the initial value of the variable i in the for loop
for (int i=len-1; i >= 0; i--) {
is incorrect because the index expression len - 1 points to the terminating zero of the source string that will be written in the first position of the new string. As a result the new array will contain an empty string.
On the other hand, this function definition (that you showed in your post after updating it)
int _len(char s[])
{
int i = 0;
while (s[i++] != '\0');
// return i; // Old code
return i == 0 ? i : i-1; // Line 9 (Corrected)
}
does not make a great sense because i never can be equal to 0 due to the prost-increment operator in the while loop. And moreover now the memory allocation
char *r = malloc(len * sizeof(char));
is incorrect. There is no space for the terminating zero character '\0'.
Also it is a bad idea to prefix identifiers with an underscore. Such names can be reserved by the system.
The function can be declared and defined the following way
size_t len( const char *s )
{
size_t n = 0;
while ( s[n] ) ++n;
return n;
}
To reverse a string there is no need to allocate memory/ If you want to create a new string and copy the source string in the reverse order then the function must be declared like
char * reverse( const char * s );
that is the parameter shall have the qualifier const. Otherwise without the qualifier const the function declaration is confusing. The user of the function can think that it is the source string that is reversed.
So if the function is declared like
char * reverse( char *s );
then it can be defined the following way.
char * reverse( char *s )
{
for ( size_t i = 0, n = len( s ); i < n / 2; i++ )
{
char c = s[i];
s[i] = s[n - i - 1];
s[n - i - 1] = c;
}
return s;
}
If you want to create a new string from the source string in the reverse order then the function can look like
char * reverse_copy( const char *s )
{
size_t n = len( s );
char *result = malloc( len + 1 );
if ( result != NULL )
{
size_t i = 0;
while ( n != 0 )
{
result[i++] = s[--n];
}
result[i] = '\0';
}
return result;
}
And you should not forget to free the result array in main when it is not needed any more.
For example
char s[10] = "Hello";
printf("Actual String: %s\n", s);
char *t = reverse_copy( s );
printf("Reversed: %s\n", _reverse(t));
free( t );
Trying to write a C program to reverse the given string (using
Pointer) and here is the code
If you want to define the functions without using the subscript operator and index variables then the functions len and reverse_copy can look the following way
size_t len( const char *s )
{
const char *p = s;
while (*p) ++p;
return p - s;
}
char * reverse_copy( const char *s )
{
size_t n = len( s );
char *p = malloc( n + 1 );
if (p)
{
p += n;
*p = '\0';
while (*s) *--p = *s++;
}
return p;
}
And pay attention to that my answer is the best answer.:)
I am trying to update string step by step in C. The code i tried is below:
#include <stdlib.h>
#include <stdio.h>
int writech(char **text, char ch) {
**text = ch;
return 1;
}
char *write(int array[], size_t size) {
char *string = (char*)malloc(sizeof(char)*(size+1));
int i, n;
for (i = 0; i < size; ++i) {
n = writech(&string, '0' + array[i]);
string += n;
}
return string;
}
int main() {
int arr[] = { 1, 2, 3, 4, 5 };
char *str = write(arr, sizeof(arr)/sizeof(arr[0]));
printf("%s\n", str);
return 0;
}
Here, write function should update string by calling other function and return updated string at the end. The code compiled and run successfully, though str (at the end of main) is empty after all. Actually, my task is to create string that contain table of some data and return it at the end. Pseudo code for my idea is below:
char *render_table() {
char *table = malloc(sizeof table);
write_header(table);
write_row(table, some_data);
write_row(table, some_data);
write_footer(table)
return table;
}
For implementing this pseudo code I wrote the above code, but not able to update passed string successfully. I know pointers are passed to function as copies, and passed memory of my string (writech(&string) to function, but string not updated still. What am i missing?
P.S. Tweaking with pointers is really struggling for me as beginner in C. What would you suggest?
string is updated. The problem is the pointer string is updated and the information of the beginning of the string is lost. You have to hold the information.
One more point is that terminating null-character must be added to pass the buffer for %s (without specifying length to print).
Also note that casting results of malloc() in C is discouraged.
Try this:
char *write(int array[], size_t size) {
char *string = malloc(sizeof(char)*(size+1));
char *cursor = string;
int i, n;
for (i = 0; i < size; ++i) {
n = writech(&cursor, '0' + array[i]);
cursor += n;
}
writech(&cursor, '\0');
return string;
}
Seems to me that you are making this much more complicated than needed.
Simply do:
for (i = 0; i < size; ++i) {
string[i] = '0' + array[i]);
}
string[i] = '\0';
If for some reason you really want to use the writech function, you can change it to:
void writech(char *text, char ch) {
*text = ch;
}
and call it like:
for (i = 0; i < size; ++i) {
writech(string + i, '0' + array[i]);
}
string[i] = '\0';
but it's really just making a simple task complex.
EDIT due to comment
If you (in your real code) don't know how many chars will be added by a function call, you simply do:
int writeSomethingA(char* str, ... other arguments ...)
{
// update str, e.g. like str[0] = 'a'; str[1] = 'b';
// or strcpy(str, "Some text");
return NumberOfCharAdded;
}
(make similar B and C versions)
and call them like:
char* string malloc(....);
int idx = 0;
idx += writeSomethingA(string + idx, ... other arguments ...);
idx += writeSomethingB(string + idx, ... other arguments ...);
idx += writeSomethingC(string + idx, ... other arguments ...);
string[idx] = '\0';
For starters it is unclear why the function writech
int writech(char **text, char ch) {
**text = ch;
return 1;
}
has the first parameter with the type char ** instead of char *.
The function can be defined like
int writech( char *text, char ch ) {
*text = ch;
return 1;
}
Within the function write the pointer string is being changed in the for loop. So the function returns a pointer that does not point to the beginning of the allocated memory.
Also as you are using the conversion specifier %s to output the character array in main then the array shall contain a string. That is the array shall have contain the terminating zero character '\0'.
The function can be implemented the following way
char * write( const int array[], size_t size ) {
char *string = malloc( size + 1 );
if ( string != NULL )
{
char *p = string;
while ( size-- ) {
p += writech( p, '0' + *array++ );
}
*p = '\0';
}
return string;
}
And you should free the allocated memory before exiting main like
free( str );
I am new with pointers on C and I am trying to write a function like strcat() but without using it. I developed the following function:
char cat(char *a, char *b) {
int i=0,cont=0,h=strlen(a)+strlen(b);
char c[h]; //new string containing the 2 strings (a and b)
for(i;i<strlen(a);++i) {
c[i] = *(a+i); //now c contains a
}
int j = i;
for(j;j<strlen(b);++j) {
c[j] = *(b+cont); //now c contains a + b
cont++;
}
return c; // I return c
}
And this is how I call the function:
printf("\Concatenazione: %c", cat(A,B));
It is now working because the final result is a weird character. How could I fix the function? Here there's the full main.
char * strcat(char *dest, const char *src)
{
int i;
int j;
for (i = 0; dest[i] != '\0'; i++);
for (j = 0; src[j] != '\0'; j++) {
dest[i+j] = src[j];
}
dest[i+j] = '\0';
return dest;
}
From your implementation it appears that your version of strcat is not compatible with the standard one, because you are looking to allocate memory for the result, rather than expecting the caller to provide you with enough memory to fit the result of concatenation.
There are several issues with your code:
You need to return char*, not char
You need to allocate memory dynamically with malloc; you cannot return a locally allocated array.
You need to add 1 for the null terminator
You need to write the null terminator into the result
You can take both parameters as const char*
You can simplify your function by using pointers instead of indexes, but that part is optional.
Here is how you can do the fixes:
char *cat(const char *a, const char *b) {
int i=0,cont=0,h=strlen(a)+strlen(b);
char *c = malloc(h+1);
// your implementation goes here
c[cont] = '\0';
return c;
}
You are returning a POINTER to the string, not the actual string itself. You need to change the return type to something like "char *" (or something equivalent). You also need to make sure to null terminate the string (append a '\0') for it to print correctly.
Taking my own advice (and also finding the other bug, which is the fact that the second for loop isn't looping over the correct indices), you end up with the following program:
#include <stdio.h>
char *cat(char *a, char *b) {
int i = 0, j = 0;
int cont = 0;
int h = strlen(a) + strlen(b) + 1;
char *result = (char*)malloc(h * sizeof(char));
for(i = 0; i < strlen(a); i++) {
result[i] = a[i];
}
for(j = i; j < strlen(b)+ strlen(a); j++) {
result[j] = b[cont++];
}
// append null character
result[h - 1] = '\0';
return result;
}
int main() {
const char *firstString = "Test First String. ";
const char *secondString = "Another String Here.";
char *combined = cat(firstString, secondString);
printf("%s", combined);
free(combined);
return 0;
}
c is a local variable. It only exists inside the function cat. You should use malloc.
instead of
char c[h];
use
char *c = malloc(h);
Also, you should add the null byte at the end. Remember, the strings in C are null-ended.
h = strlen(a) + strlen(b) + 1;
and at the end:
c[h - 1] = '\0';
The signature of cat should be char *cat(char *a, char *b);
You will get an error of
expected constant expression
for the code line char c[h];. Instead you should be using malloc to allocate any dynamic memory at run-time like::
char* c ;
c = malloc( h + 1 ) ; // +1 for the terminating null char
// do stuff
free( c ) ;
Your corrected code::
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include <stdlib.h>
char* cat(char *a, char *b) {
int i=0,cont=0,h=strlen(a)+strlen(b), j;
char *c;
c = malloc( h+1 ) ;
for(i;i<strlen(a);++i) {
c[i] = *(a+i);
}
j = 0 ;
for(j;j<strlen(b);++j) {
c[i] = *(b+cont);
i++ ;
cont++;
}
c[i] = 0 ;
return c;
}
int main() {
char A[1000],B[1000];
char * a ;
printf("Inserisci la stringa 1: \n");
gets(A);
printf("Inserisci la stringa 2: \n");
gets(B);
a = cat(A,B) ;
printf("\nConcatenazione: %s", a);
free(a) ;
getch();
return 0;
}