【问题标题】:How to concatenate two string array index by index in C?如何在C中按索引连接两个字符串数组索引?
【发布时间】:2019-02-14 09:34:23
【问题描述】:

我有两个名为namesubject 的字符串数组。我想要另一个字符串数组,其元素是通过将第一个数组的字符串与另一个数组具有相同索引的字符串连接来获得的。新数组应该是函数的输出。

这里我给出了一个代码示例,但由于出现错误,我无法编译。 我也见过this question,但我无法使用它。

谁能告诉我如何在没有动态分配和动态分配的情况下解决这个问题?

#include <stdio.h>
#include <string.h> 
const int MAX = 4;
char* concancate_string(char* name,char* subject);

int main () {

char* name[] = {
  "michel",
  "sam",
  "roy",
  "romi"
};
char* subject[] = {
  "physics",
  "math",
  "chemistry",
  "biology"
};
char* p[];
p=concancate_string(name,subject);
for ( int i = 0; i < MAX; i++) {
      printf("name and subject[%d] = %s\n", i, name[i] );
}

return 0;

}

char* concancate_string(char* name,char* subject)
{
    for ( int i = 0; i < MAX; i++) {
      strcat(name[i]," : ");
      strcat(name[i],subject[i]);
    }
    return name;
}


resulted output array:
{
 "michel : physics",
 "sam : math",
 "roy : chemistry",
 "romi : biology"
} 

【问题讨论】:

  • 如果没有动态分配,IMO 是不可能的。

标签: c arrays string


【解决方案1】:

这是我对动态分配的尝试:

char **concancate_string(const char *name[], const char *subject[], size_t n) {
    char **destin = malloc(n * sizeof *destin);
    for (int i = 0; i < n; i++) {
        destin[i] = malloc(strlen(name[i]) + strlen(subject[i]) + 3 + 1); // add space for " : " and terminating '\0'
        sprintf(destin[i], "%s : %s", name[i], subject[i]);
    }
    return destin;
}

请记住所有free(destin[k])free(destin)

code running on https://ideone.com/3Qb7v1

【讨论】:

  • sizeof *destin 是否等同于 sizeof (char*)
  • @FrancescoBoi:在这种情况下,是的。我发现使用对象本身而不是类型更好。
  • 恭喜!
【解决方案2】:

首先,这个声明不起作用:

char* p[]; // how much stack memory should the compiler reserve?
p=concancate_string(name,subject); // can't assign to an array

相反,这样做:

char **p = concancate_string(name, subject); // you can assign to pointers, though

这个签名也是错误的:

char* concancate_string(char* name,char* subject);

它接收和返回 char* 的数组,而不是单个 char*,所以应该是:

char **concancate_string(char **name, char **subject);

此外,您不能连接到分配了字符串文字的指针。这些指向您程序的二进制文件,它是只读的。相反,该函数应如下所示:

char **concancate_string(char **name, char **subject)
{
    char **pointers = malloc(MAX * sizeof(char*));
    for (int i = 0; i < MAX; i++) {
        pointers[i] = malloc(strlen(name[i]) + strlen(subject[i]) + 4);
        sprintf(pointers[i], "%s : %s", name[i], subject[i]);
    }
    return pointers;
}

注意我们如何为指针分配一个数组,然后为每个字符串分配内存,然后使用sprintf 组装它们(当然,您也可以使用strcpystrcat)。

最后,您的打印错误。你创建了p,但不是打印它,而是打印name。它应该是:

printf("name and subject[%d] = %s\n", i, p[i]);

当你完成后,应该释放内存:

for (int i = 0; i < MAX; i++) {
    free(p[i]);
}
free(p);

我对你的建议是在一部分时间编写程序,只有在最后一部分经过测试并且运行良好时才从下一部分开始。如果您只是编写整个程序而没有测试,然后由于到处都是错误而无法正常工作,那么找到它们就会变得更加困难。

【讨论】:

  • 谢谢。你能解释一下为什么我们需要双指针来传递和返回字符串数组到函数吗?另外,我们可以在没有动态分配的情况下做同样的事情吗? @Blaze
  • @ray123 字符串本身表示为char*,所以如果你有一个完整的数组,那么它就是char* 的数组,所以是*char[]。您可以在签名中写*name[] 而不是**name(结果相同),但这不适用于返回类型,必须为**concancate_string,因为您不能返回字符串。没有动态分配能做到吗?好吧,您可以在堆栈上固定缓冲区并在那里复制字符串,但这将是一个相当大的问题并且有自己的警告,所以我会说它不会再解决相同的任务了。
【解决方案3】:

如果您可以假设每个字符串的最大长度,则无需使用动态分配。在下面的示例(编译并运行)中,我假设每个字符串的长度为 100(99 个可用字符加上 \0 字符)。

所以我使用您的MAX 常量和100 作为char result[MAX][100] = {0}; 定义了一个数组。 {0} 将所有元素初始化为 0(此初始化仅适用于 0。然后我将这个新数组传递给函数。请注意,您将函数参数定义为 char* name,这意味着一个字符串:您要传递一个字符串数组:我重新定义为concancate_string(char* name[], char* subject[], char out[MAX][100]):注意区别。

字符串与strcat 简单连接。还有另一个函数strncat 允许您指定要复制的最大字符数。

#include <stdio.h>
#include <string.h>
const int MAX = 4;
int concancate_string(char* name[], char* subject[], char out[MAX][100]);

int main () {
  char result[MAX][100] = {0} ;
  char* name[] = {
    "michel",
    "sam",
    "roy",
    "romi"
  };
  char* subject[] = {
    "physics",
    "math",
    "chemistry",
    "biology"
  };
  int p=concancate_string(name, subject, result);
  for ( int i = 0; i < MAX; i++) {
    printf("%s\n", result[i] );
  }

  return 0;

}

int concancate_string(char* name[], char* subject[], char out[MAX][100])
{
  for ( int i = 0; i < MAX; i++) {
    strcat(out[i], name[i]);
    //printf("%s\n", out[i] );
    strcat(out[i], " : ");
    //printf("%s\n", out[i] );
    strcat(out[i], subject[i]);
    //printf("%s\n", out[i] );
  }
  retur

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-08
    • 2019-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    相关资源
    最近更新 更多