C中没有库的字符串连接

String concatenation without libraries in C

我在没有库函数的情况下在 C 中连接字符串时遇到问题。 我尝试了以下方法:

#include <stdio.h>

struct word {
  char *str;
  int wordSize;
};

void concat(struct word words[], int arraySize, int maxSize) { // word array, its size, and max size given
  char result[maxSize];
  int resultSize = 0;
  struct word tmp;

  for (int i = 0; i < arraySize; i++) {
    tmp = words[i];
    for (int j = 0; j < words[i].wordSize; j++,  resultSize++) {
      result[resultSize + j] = tmp.str[j];
    }
  }

  puts(result);
}

例如,如果结构数组 words 包含 [{"he", 2}, {"ll", 2}, {"o", 1}],则 result 应该是 hello。但是,此代码打印 h�l�o 其中第二个和第四个字母是问号。谁能帮我调试一下?

保持简单,错误会自行修复。不要将 result 缓冲区中的位置与循环迭代器混淆。不需要临时变量。

#include <stdio.h>

typedef struct {
  char *str;
  int wordSize;
} word;

void concat(word words[], int arraySize, int maxSize) { 
  char result[maxSize];
  int count=0;
  
  for(int i=0; i<arraySize; i++)
  {
    for(int j=0; j<words[i].wordSize; j++)
    {
      result[count]= words[i].str[j];
      count++;
    }
  }
  result[count] = '[=10=]';
  
  puts(result);
}

int main()
{
  word w[3] = { {"he", 2}, {"ll", 2}, {"o", 1} };
  concat(w, 3, 128);
}

你这里有几个问题。 result[resultSize + j] 意味着您实际上跳过了结果中一半的字符。其次,如果您复制整个字符串,包括空字符,puts 将在第一个单词本身的末尾停止打印结果字符串。因此,您需要跳过复制字符串终止符并将其放在整个连接字符串的末尾。

#include <stdio.h>

struct word {
  char *str;
  int wordSize;
};

void concat(struct word words[], int maxSize) { // word array and max size given
  char result[maxSize];
  int resultSize = 0;
  struct word tmp;

  for (int i = 0; i < 3; i++) {
    tmp = words[i];
    // Keep copying the words to result, one after the other
    // But drop the last NULL character
    for (int j = 0; j < (words[i].wordSize - 1); j++,  resultSize++) {      
      result[resultSize] = tmp.str[j]; 
    }
  }
  // Put the NULL character in after all words have been copied
  result[resultSize] = 0;
  puts(result);
}

struct word mywords[] = 
{
  { "TestWord", sizeof("TestWord")},
  { "TestWord2", sizeof("TestWord2")}
};

int main(void)
{
  concat(mywords, 100);
  return 0;
}

在这个for循环中

for (int j = 0; j < words[i].wordSize; j++,  resultSize++) {
  result[resultSize + j] = tmp.str[j];
}

您正在同时增加 resultSizej,而您只需要增加变量 j 并在循环后将变量 resultSize 增加 j.

但无论如何函数都是错误的,因为没有检查 resultSize 是否小于 maxSize

此外,构建的字符串没有附加终止零 '[=22=]'。结果这个声明

puts(result);

调用未定义的行为。

无需创建变长数组

char result[maxSize];

只是为了输出连接的字符串。

函数可以按照下面的演示程序所示的方式声明和定义。

#include <stdio.h>

struct word {
  char *str;
  int wordSize;
};

void concat( const struct word words[], size_t arraySize, size_t maxSize )
{
    for ( size_t i = 0, j = 0; i < maxSize && j < arraySize; j++ )
    {
        for ( size_t k = 0; i < maxSize && k < words[j].wordSize; i++, k++ )
        {
            putchar( words[j].str[k] );
        }
    }
    
    putchar( '\n' );
}

int main(void) 
{
    struct word words[] =
    {
        { "he", 2 }, { "ll", 2 }, { "o", 1 }
    };
    const size_t arraySize = sizeof( words ) / sizeof( *words );
    
    concat( words, arraySize, 5 );
    
    return 0;
}

程序输出为

hello