简体   繁体   English

返回一个指向`char`的指针数组

[英]Returning an array of pointers to `char`

This program should concatenate strings, But I don't know how return the string array back to main. 这个程序应该连接字符串,但是我不知道如何将字符串数组返回给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 : 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? 如何在main中打印串联的字符串?

You need return char* instead of array of pointer to char . 你需要返回char*代替指针数组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);
}

Reason of segfault is you can not initialize memory for *conc[i] like that : segfault的原因是您无法像这样初始化* conc [i]的内存:

*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. conc是指针数组,存储在conca()的堆栈帧中,因此从技术上来讲,这是未定义的行为。 The solution is to change conc to a char ** and use malloc() to allocate the whole array (and remember to free it later) 解决方案是将conc更改为char **,然后使用malloc()分配整个数组(并记住稍后释放它)

So i modified your char **conca(char *a[], int n) function. 所以我修改了char ** conca(char * a [],int n)函数。 so i used **conc instead of array of pointer. 所以我用** conc代替了指针数组。

#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");
}

Instead of returning char ** , You should return char * . 您应该返回char *而不是返回char **

There is also no error checking on malloc , which is needed since you can return a NULL pointer if unsuccessful. malloc上也没有错误检查,这是必需的,因为如果失败,您可以返回NULL指针。

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

the following code: 以下代码:

  1. cleanly compiles 干净地编译
  2. performs the desired functionality 执行所需的功能
  3. properly outputs error messages to stderr 正确将错误消息输出到stderr
  4. properly checks for errors 正确检查错误
  5. includes the proper #include statements 包含正确的#include语句
  6. is appropriately commented 被适当评论
  7. contains some the original posted code as comments to highlite where changes were made 包含一些原始发布的代码,作为对Highlite进行更改的注释
  8. avoids unnecessary variables 避免不必要的变量
  9. displays the resulting concatenated string 显示结果连接字符串
  10. cleans up after itself 自行清理

and 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM