Reputation: 25
This program should concatenate strings, But I don't know how return the string array back to main.
char **conca(char *a[], int n)
{
char buff[200];
char **conc[n];
for (int i = 0; i < n; i++)
{
strcpy(buff,a[i]);
strcat(buff,"-");
int l = strlen(buff);
*conc[i] = malloc((l+1)*sizeof(char));
strcpy(*conc[i],buff);
}
return *conc;
In main.c
:
char **conca(char *a[], int n);
int main(int argc, char *argv[])
{
if(argc == 1)
{
printf("Uso: %s <stringa> <stringa> ... <stringa> \n",argv[0]);
return 1;
}
int dim = argc - 1;
int pos = 0;
char *array[dim];
for(int i = 1; i <= dim; i++ )
{
array[pos] = malloc((strlen(argv[i])+1)*sizeof(char));
strcpy(array[pos],argv[i]);
pos++;
}
char **f = conca(array, dim);
}
The program triggers a segmentation fault (core dump).
How can I print the concatenated string in main?
Upvotes: 0
Views: 121
Reputation: 16540
the following code:
#include
statementsand now the code
#include <stdio.h> // printf(), fprintf()
#include <stdlib.h> // exit(), EXIT_FAILURE, malloc(), realloc(), free()
#include <string.h> // strlen(), strcat()
//char **conca(char *a[], int n);
// function prototypes
char *concat(char *argv[], int argc);
int main(int argc, char *argv[])
{
if(argc == 1)
{
fprintf( stderr, "Uso: %s <stringa> <stringa> ... <stringa> \n",argv[0]);
//printf("Uso: %s <stringa> <stringa> ... <stringa> \n",argv[0]);
exit( EXIT_FAILURE );
//return 1;
}
char *newCat = concat( argv, argc );
printf( "%s\n", newCat );
free( newCat );
} // end function: main
char *concat(char *argv[], int argc)
{
char *newString = malloc(1);
if( !newString )
{ // then malloc failed
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
newString[0] = '\0';
for( int i = 1; i <= argc; i++ )
//for(int i = 1; i <= dim; i++ )
{
char * tempptr = realloc( newString, strlen( newString) + strlen(argv[i])+2 );
if( !tempptr )
{ // then realloc failed
perror( "realloc failed" );
free( newString );
exit( EXIT_FAILURE );
}
// implied else, realloc successful
newString = tempptr;
//array[pos] = malloc((strlen(argv[i])+1)*sizeof(char));
//strcpy(array[pos],argv[i]);
strcat( newString, argv[i] );
// avoid a trailing '-' in final string
if( i < (argc-1) )
{
strcat( newString, "-" );
}
} // end for
return newString;
} // end function: concat
Upvotes: 0
Reputation: 26335
Instead of returning char **
, You should return char *
.
There is also no error checking on malloc
, which is needed since you can return a NULL
pointer if unsuccessful.
Here is an example that shows this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *join(char *argv[], int n);
int main(int argc, char *argv[]){
char *result;
if(argc == 1){
printf("Uso: %s <stringa> <stringa> ... <stringa> \n", argv[0]);
return 1;
}
result = join(argv, argc);
printf("%s\n", result);
free(result);
result = NULL;
return 0;
}
char *join(char *argv[], int n) {
int i;
const char *sep = "-";
char *string;
size_t strsize = 0;
for (i = 1; i < n; i++) {
strsize += strlen(argv[i])+1;
}
string = malloc(strsize);
if (!string) {
printf("Cannot allocate memory for string.\n");
exit(EXIT_FAILURE);
}
*string = '\0';
for (i = 1; i < n; i++) {
strcat(string, argv[i]);
if (i < n-1) {
strcat(string, sep);
}
}
return string;
}
Input:
$ gcc -Wall -Wextra -Wpedantic -std=c99 -o concat concat.c
$ ./concat Always check return of malloc
Output:
Always-check-return-of-malloc
Upvotes: 0
Reputation: 40155
You need return char*
instead of array of pointer to char
.
Like this
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *join(char *a[], int n, char sep){
size_t lens[n], total_length = 0;
for (int i = 0; i < n; i++){
total_length += (lens[i] = strlen(a[i]));
}
total_length += n;//sep * (n-1) + NUL
char *ret = malloc(total_length);
char *wk = ret;
for (int i = 0; i < n; i++){
if(i)
*wk++ = sep;
memcpy(wk, a[i], lens[i]);
wk += lens[i];
}
*wk = 0;
return ret;
}
int main(int argc, char *argv[]){
if(argc == 1){
printf("Uso: %s <stringa> <stringa> ... <stringa> \n", argv[0]);
return 1;
}
int dim = argc - 1;
char *concata = join(argv+1, dim, '-');
puts(concata);
free(concata);
}
Upvotes: 2
Reputation: 1836
Reason of segfault is you can not initialize memory for *conc[i] like that :
*conc[i] = malloc((l+1)*sizeof(char))
instead you have to do
conc[i] = malloc((l+1)*sizeof(char))
But you have another problem here. You're declaring the array as a local variable. conc is an array of pointers which is stored in conca()'s stack frame, so this is, technically speaking, undefined behavior. The solution is to change conc to a char ** and use malloc() to allocate the whole array (and remember to free it later)
So i modified your char **conca(char *a[], int n) function. so i used **conc instead of array of pointer.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **conca(char *a[], int n)
{
char buff[200];
char **conc = (char **)malloc(n*sizeof(char *));
int i=0;
for (i = 0; i < n; i++)
{
strcpy(buff,a[i]);
strcat(buff,"-");
int l = strlen(buff);
conc[i]=(char *)malloc((l+1)*sizeof(char));
strcpy(conc[i],buff);
}
return conc;
}
int main(int argc, char *argv[])
{
if(argc == 1)
{
printf("Uso: %s <stringa> <stringa> ... <stringa> \n",argv[0]);
return 1;
}
int dim = argc - 1;
int pos = 0;
char *array[dim];
int i=0;
for(i = 1; i <= dim; i++ )
{
array[pos] = malloc((strlen(argv[i])+1)*sizeof(char));
strcpy(array[pos],argv[i]);
pos++;
pos++;
}
char **f = conca(array, dim);
for(i=0;i<dim;i++)
printf("%s",f[i]);
printf("\n\n");
}
Upvotes: 0