【问题标题】:can't concat strings via another string in c不能通过c中的另一个字符串连接字符串
【发布时间】:2020-09-08 23:16:25
【问题描述】:

例如

array = ["abc", "def", "xx"] , concat_string = "-"

output: "abc-def-xx"

我得到了“abc-”

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#ifndef STRUCT_STRING_ARRAY
#define STRUCT_STRING_ARRAY
typedef struct s_string_array
{
    int size;
    char** array;
} string_array;
#endif


char* my_join(string_array* param_1, char* param_2)
{
    int len = param_1->size;
    if(len == 0){
        return NULL;
    }

    char **my_arr = param_1->array;
    int total_len = 0;//this is to create array that will store the entire string , i need total length to know how much malloc to do

    for(int i = 0 ; i < len;i++){
        total_len += strlen(my_arr[i]) + strlen(param_2);
    }

    char *res;
    //char res[total_len];//tried this but it did not work
    for(int i = 0; i < len-1;i++){
        strncat(my_arr[i], param_2, 1);//concat the string- add param_2 to my-arr
        strncat(res, my_arr[i],1); //concat every my_arr to res
    }

    return res;
}


int main(){

    struct s_string_array s= {
        .size = 3,
        .array = (char*[]){"abc", "def", "gh"}

    };

    char *t = "-";

    my_join(&s,t);
    return 0;
}

为什么会停在“abc”?

【问题讨论】:

  • char *res; 是一个未初始化的指针,它指向没有有效的内存。 strncat(res, my_arr[i],1); 调用 Undefined Behavior 试图将其用作目标。
  • @DavidC.Rankin,等等,但 res 是我的目的地,哦,你的意思是 res 是空的,我通过 strncat 复制到空字符串?
  • 我的意思是res 没有指向任何东西,您尝试连接到未初始化指针的末尾。这样想,char *res; 声明了一个 指向 char 的指针,但它指向的是哪个 char?在您可以连接到该内存位置之前,它必须指向一些能够存储字符的有效存储。在它确实指向有效存储之后,*res = some_char;strncat(res, my_arr[i],1); 简单得多...
  • 是的,分配内存是必须的。您将需要分配 .array 中每个字符串的 strlen() 的总和,加上要为 nul-terminating 插入 +1'-' 两个字符特点。 (至少 11 字节)
  • 根据man page。 “目标字符串必须有足够的空间用于结果。”因此strncat(res, my_arr[i],1); 将不起作用,因为res 的值是不确定的。 strncat(my_arr[i], param_2, 1); 将不起作用,因为 my_arr 的每个元素都是非法写入的字符串文字。对于第一个问题,char res[total_len]; 如果您使用的是最近的 c 编译器,实际上应该可以工作,但对于第二个问题,您需要动态分配 my_arr 的元素或分配大尺寸的元素。

标签: c arrays struct char c99


【解决方案1】:

要解决未初始化的指针和分配问题,您可以使用malloc()res 分配内存(不要忘记验证分配),然后将res 初始化为空字符串 em>,并按如下方式调整您的连接:

char* my_join(string_array* param_1, char* param_2)
{
    int len = param_1->size;
    if(len == 0){
        return NULL;
    }

    char **my_arr = param_1->array;
    int total_len = 0;

    for(int i = 0 ; i < len;i++){       /* if param_2 greater than 1-char, you over-allocate */
        total_len += strlen(my_arr[i]) + strlen(param_2);
    }

    char *res = malloc (total_len);     /* allocate / validate */
    if (!res) {
        perror ("malloc-res");
        return NULL;
    }
    *res = 0;                           /* make res empty-string */

    for (int i = 0; i < len; i++) {
        strcat (res, my_arr[i]);        /* concatenate my_arr[i] */
        if (i < len-1)                  /* if not end */
            strcat (res, param_2);      /* concatenate param_2 */
    }

    return res;
}

还要注意strncat(my_arr[i], param_2, 1); 调用未定义行为。您使用 compound 文字来强制转换为指针数组,但初始化是使用 string-literals - 它们的内容无法更改。

【讨论】:

    猜你喜欢
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    • 2015-01-04
    • 1970-01-01
    • 2011-09-20
    相关资源
    最近更新 更多