用分隔符连接C中的字符串
我正在尝试编写一个函数,用分隔符连接字符串。以下是我到目前为止的情况:用分隔符连接C中的字符串,c,string,function,C,String,Function,我正在尝试编写一个函数,用分隔符连接字符串。以下是我到目前为止的情况: int main(void) { char * strings[] = {"A", "B", NULL}; char ** copied_strings = malloc(sizeof strings); // Join strings with a separator char * separator = "XXX"; size_t num_array_elements = (s
int main(void) {
char * strings[] = {"A", "B", NULL};
char ** copied_strings = malloc(sizeof strings);
// Join strings with a separator
char * separator = "XXX";
size_t num_array_elements = (sizeof strings / sizeof * strings) - 1; // because last element is NULL
size_t len_separator = strlen(separator);
size_t len_strings = 0;
for (int i=0; strings[i] != NULL ;i++) len_strings += strlen(strings[i]);
size_t malloc_buffer_size = len_strings + (len_separator * (num_array_elements -1)) + 1;
printf("Separator: %s | Len Array: %lu | Len Strings: %lu | Malloc Buffer Size: %lu\n", separator, num_array_elements, len_strings, malloc_buffer_size);
char * joined_string_buffer = malloc(malloc_buffer_size);
join_strings(joined_string_buffer, copied_strings, separator);
}
void join_strings(char * joined_string_buffer, char ** src, char * separator) {
size_t sep_len = strlen(separator);
while (*src) {
size_t string_len = strlen(*src);
for (int i=0; i<string_len; i++)
*joined_string_buffer++ = (*src)[i];
for (int i=0; i<sep_len; i++)
*joined_string_buffer++ = separator[i];
*src++;
}
*joined_string_buffer = '\0';
}
int main(无效){
字符*字符串[]={“A”,“B”,NULL};
char**copied_strings=malloc(字符串大小);
//用分隔符连接字符串
char*separator=“XXX”;
size\t num\u array\u elements=(sizeof strings/sizeof*strings)-1;//因为最后一个元素为NULL
尺寸长度分隔符=strlen(分隔符);
长度字符串的大小=0;
对于(int i=0;strings[i]!=NULL;i++)len_strings+=strlen(strings[i]);
size_t malloc_buffer_size=len_strings+(len_分隔符*(num_数组元素-1))+1;
printf(“分隔符:%s | Len数组:%lu | Len字符串:%lu | Malloc缓冲区大小:%lu\n”,分隔符,num |数组元素,Len |字符串,Malloc |缓冲区大小);
char*joined\u string\u buffer=malloc(malloc\u buffer\u size);
连接字符串(连接字符串缓冲区、复制字符串、分隔符);
}
无效联接字符串(字符*联接字符串\缓冲区,字符**src,字符*分隔符){
尺寸sep_len=strlen(分离器);
while(*src){
尺寸字符串长度=strlen(*src);
对于(int i=0;i#包括
#包括
#包括
无效连接字符串(字符*连接字符串\缓冲区,常量字符*src[],常量字符*分隔符);
内部主(空){
常量字符*字符串[]={A”,“B”,NULL};
char**copied_strings=(char**)malloc(sizeof strings);
//用分隔符连接字符串
常量字符*分隔符=“XXX”;
size\t num\u array\u elements=(sizeof strings/sizeof*strings)-1;//因为最后一个元素为NULL
尺寸长度分隔符=strlen(分隔符);
长度字符串的大小=0;
对于(int i=0;strings[i]!=NULL;i++)len_strings+=strlen(strings[i]);
size_t malloc_buffer_size=len_strings+(len_分隔符*(num_数组元素-1))+1;
printf(“分隔符:%s | Len数组:%lu | Len字符串:%lu | Malloc缓冲区大小:%lu\n”,分隔符,num |数组元素,Len |字符串,Malloc |缓冲区大小);
char*连接的字符串缓冲区=(char*)malloc(malloc\u缓冲区大小);
连接字符串(连接字符串缓冲区、字符串、分隔符);
//结果是AXXXBXXX
printf(“%s\n”,已加入字符串缓冲区);
}
无效联接字符串(字符*联接字符串\缓冲区,常量字符*src[],常量字符*分隔符){
尺寸sep_len=strlen(分离器);
while(*src){
尺寸字符串长度=strlen(*src);
对于(int i=0;i
我想您在选择'join_strings'的第二个参数时犯了一个错误。\include
#包括
#包括
无效连接字符串(字符*连接字符串\缓冲区,常量字符*src[],常量字符*分隔符);
内部主(空){
常量字符*字符串[]={A”,“B”,NULL};
char**copied_strings=(char**)malloc(sizeof strings);
//用分隔符连接字符串
常量字符*分隔符=“XXX”;
size\t num\u array\u elements=(sizeof strings/sizeof*strings)-1;//因为最后一个元素为NULL
尺寸长度分隔符=strlen(分隔符);
长度字符串的大小=0;
对于(int i=0;strings[i]!=NULL;i++)len_strings+=strlen(strings[i]);
size_t malloc_buffer_size=len_strings+(len_分隔符*(num_数组元素-1))+1;
printf(“分隔符:%s | Len数组:%lu | Len字符串:%lu | Malloc缓冲区大小:%lu\n”,分隔符,num |数组元素,Len |字符串,Malloc |缓冲区大小);
char*连接的字符串缓冲区=(char*)malloc(malloc\u缓冲区大小);
连接字符串(连接字符串缓冲区、字符串、分隔符);
//结果是AXXXBXXX
printf(“%s\n”,已加入字符串缓冲区);
}
无效联接字符串(字符*联接字符串\缓冲区,常量字符*src[],常量字符*分隔符){
尺寸sep_len=strlen(分离器);
while(*src){
尺寸字符串长度=strlen(*src);
对于(int i=0;i
我想您在选择'join_strings'的第二个参数时犯了一个错误。代码中有很多问题,但它们大部分都是细节。不幸的是,在编程中,甚至细节都必须正确。此代码修复了大多数问题,其中大部分问题都在注释中确定
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void join_strings(char *joined_string_buffer, char **src, char *separator);
int main(void)
{
char *strings[] = { "A", "B", NULL };
char *separator = "XXX";
size_t num_array_elements = (sizeof strings / sizeof *strings) - 1; // because last element is NULL
size_t len_separator = strlen(separator);
size_t len_strings = 0;
for (int i = 0; strings[i] != NULL; i++)
len_strings += strlen(strings[i]);
size_t malloc_buffer_size = len_strings + (len_separator * (num_array_elements - 1)) + 1;
printf("Separator: '%s' | Len Array: %zu | Len Strings: %zu | Malloc Buffer Size: %zu\n",
separator, num_array_elements, len_strings, malloc_buffer_size);
char *joined_string_buffer = malloc(malloc_buffer_size);
if (joined_string_buffer == 0)
{
fprintf(stderr, "failed to allocate %zu bytes of memory\n", malloc_buffer_size);
exit(EXIT_FAILURE);
}
join_strings(joined_string_buffer, strings, separator);
printf("[[%s]]\n", joined_string_buffer);
free(joined_string_buffer);
return 0;
}
static void join_strings(char *joined_string_buffer, char **src, char *separator)
{
size_t sep_len = strlen(separator);
while (*src)
{
size_t string_len = strlen(*src);
for (size_t i = 0; i < string_len; i++)
*joined_string_buffer++ = (*src)[i];
for (size_t i = 0; i < sep_len; i++)
*joined_string_buffer++ = separator[i];
src++;
}
*joined_string_buffer = '\0';
}
请注意,“分隔符”更严格地说是一个“终止符”——它出现在列表中最后一项之后以及两者之间
显示的代码或多或少是对问题中代码的直接修复。但是main()
和join\u strings()
函数中的代码之间的工作划分不好。这是一种更好的职责分离:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char *join_strings(char **src, char *separator);
int main(void)
{
char *strings[] = { "A", "B", NULL };
char *separator = "XXX";
char *result = join_strings(strings, separator);
printf("[[%s]]\n", result);
free(result);
return 0;
}
static char *join_strings(char **src, char *separator)
{
size_t len_sep = strlen(separator);
size_t num_str = 0;
for (size_t i = 0; src[i] != NULL; i++)
num_str++;
size_t len_str = 0;
for (int i = 0; src[i] != NULL; i++)
len_str += strlen(src[i]);
size_t buf_len = len_str + (len_sep * num_str) + 1;
printf("Separator: '%s' | Len Array: %zu | Len Strings: %zu | Malloc Buffer Size: %zu\n",
separator, num_str, len_str, buf_len);
char *result = malloc(buf_len);
if (result == 0)
{
fprintf(stderr, "failed to allocate %zu bytes of memory\n", buf_len);
exit(EXIT_FAILURE);
}
char *dst = result;
for (size_t i = 0; src[i] != NULL; i++)
{
char *str = src[i];
for (size_t j = 0; str[j] != '\0'; j++)
*dst++ = str[j];
for (size_t i = 0; i < len_sep; i++)
*dst++ = separator[i];
}
*dst = '\0';
return result;
}
#包括
#包括
#包括
静态字符*连接字符串(字符**src,字符*分隔符);
内部主(空)
{
字符*字符串[]={“A”,“B”,NULL};
char*separator=“XXX”;
char*result=连接字符串(字符串、分隔符);
printf(“[[%s]]\n”,结果);
自由(结果);
返回0;
}
静态字符*连接字符串(字符**src,字符*分隔符)
{
尺寸长度sep=strlen(分离器);
大小\u t num\u str=0;
对于(大小i=0;src[i]!=NULL;i++)
num_str++;
尺寸长度长度=0;
for(int i=0;src[i]!=NULL;i++)
len_str+=strlen(src[i]);
长度=长度+长度(长度*长度)+1;
printf(“分隔符:“%s”| Len数组:%zu | Len字符串:%zu | Malloc缓冲区大小:%zu\n”,
分隔符,num_str,len_str,buf_len);
char*result=malloc(buf_len);
如果(结果==0)
{
fprintf(stderr,“分配%zu字节内存失败”,buf_len);
退出(退出失败);
}
char*dst=结果;
对于(大小i=0;src[i]!=NULL;i++)
{
char*str=src[i];
对于(大小j=0;str[j]!='\0';j++)
Separator: 'XXX' | Len Array: 2 | Len Strings: 2 | Malloc Buffer Size: 6
[[AXXXBXXX]]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char *join_strings(char **src, char *separator);
int main(void)
{
char *strings[] = { "A", "B", NULL };
char *separator = "XXX";
char *result = join_strings(strings, separator);
printf("[[%s]]\n", result);
free(result);
return 0;
}
static char *join_strings(char **src, char *separator)
{
size_t len_sep = strlen(separator);
size_t num_str = 0;
for (size_t i = 0; src[i] != NULL; i++)
num_str++;
size_t len_str = 0;
for (int i = 0; src[i] != NULL; i++)
len_str += strlen(src[i]);
size_t buf_len = len_str + (len_sep * num_str) + 1;
printf("Separator: '%s' | Len Array: %zu | Len Strings: %zu | Malloc Buffer Size: %zu\n",
separator, num_str, len_str, buf_len);
char *result = malloc(buf_len);
if (result == 0)
{
fprintf(stderr, "failed to allocate %zu bytes of memory\n", buf_len);
exit(EXIT_FAILURE);
}
char *dst = result;
for (size_t i = 0; src[i] != NULL; i++)
{
char *str = src[i];
for (size_t j = 0; str[j] != '\0'; j++)
*dst++ = str[j];
for (size_t i = 0; i < len_sep; i++)
*dst++ = separator[i];
}
*dst = '\0';
return result;
}
char *joinstr (const char **s, const char *sep)
{
char *joined = NULL; /* pointer to joined string w/sep */
size_t lensep = strlen (sep), /* length of separator */
sz = 0; /* current stored size */
int first = 1; /* flag whether first term */
while (*s) { /* for each string in s */
size_t len = strlen (*s);
/* allocate/reallocate joined */
void *tmp = realloc (joined, sz + len + (first ? 0 : lensep) + 1);
if (!tmp) { /* validate allocation */
perror ("realloc-tmp"); /* handle error (adjust as req'd) */
exit (EXIT_FAILURE);
}
joined = tmp; /* assign allocated block to joined */
if (!first) { /* if not first string */
strcpy (joined + sz, sep); /* copy separator */
sz += lensep; /* update stored size */
}
strcpy (joined + sz, *s++); /* copy string to joined */
first = 0; /* unset first flag */
sz += len; /* update stored size */
}
return joined; /* return joined string */
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
...
int main (void) {
const char *strings[] = {"A", "B", NULL},
*sep = "XXX";
char *joined = joinstr (strings, sep); /* join strings */
printf ("%s\n", joined); /* output joined string */
free (joined); /* free memory */
}
$ ./bin/joinwsep
AXXXB
$ valgrind ./bin/joinwsep
==17127== Memcheck, a memory error detector
==17127== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==17127== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==17127== Command: ./bin/joinwsep
==17127==
AXXXB
==17127==
==17127== HEAP SUMMARY:
==17127== in use at exit: 0 bytes in 0 blocks
==17127== total heap usage: 2 allocs, 2 frees, 8 bytes allocated
==17127==
==17127== All heap blocks were freed -- no leaks are possible
==17127==
==17127== For counts of detected and suppressed errors, rerun with: -v
==17127== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
void write_strings(FILE* stream, int count, char** src, char* separator) {
for(int i = 0; i < count; i++) {
fprintf(stream, "%s%s", src[i], separator);
}
}
char* join_strings(int count, char** src, char* separator) {
char* result = NULL;
size_t length = 0;
FILE* stream = open_memstream(&result, &length);
write_strings(stream, count, src, separator);
fclose(stream);
return result;
}
int main(void) {
char * strings[] = {"A", "B"}; //no terminator necessary
size_t num_array_elements = sizeof strings / sizeof * strings;
char * separator = "XXX";
printf("Separator: %s | Len Array: %lu\n", separator, num_array_elements);
char * joined_string_buffer = join_strings(num_array_elements, strings, separator);
//Added by me: Print the result to stdout
printf("Resulting string: \"%s\" (%d characters)\n", joined_string_buffer, strlen(joined_string_buffer));
//Cleanup: Free the buffer allocated by `open_memstream()`
free(joined_string_buffer);
}