简体   繁体   English

C中没有库的字符串连接

[英]String concatenation without libraries in C

I am having trouble concatenating strings in C without library function.我在没有库函数的情况下在 C 中连接字符串时遇到问题。 I tried the following:我尝试了以下方法:

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

For example, if the struct array words contain [{"he", 2}, {"ll", 2}, {"o", 1}] , the result should be hello .例如,如果结构数组words包含[{"he", 2}, {"ll", 2}, {"o", 1}]result应该是hello However, this code prints h l o where the second and fourth letters are questionmark.但是,此代码打印h l o ,其中第二个和第四个字母是问号。 Can anyone help me debug this?谁能帮我调试一下?

Keep it simple and the bugs will fix themselves.保持简单,错误会自行修复。 Don't mix up the position in the result buffer with the loop iterators.不要将result缓冲区中的位置与循环迭代器混淆。 No need for temporary variables.不需要临时变量。

#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] = '\0';
  
  puts(result);
}

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

In this for loop在这个 for 循环中

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

you are incrementing resultSize and j simultaneously while you need to increase only the variable j and after the loop increase the variable resultSize by j .您同时增加resultSizej ,而您只需要增加变量j并且在循环之后将变量resultSize增加j

But in any case the function is wrong because there is no check that resultSize is less than maxSize .但无论如何该函数都是错误的,因为没有检查resultSize是否小于maxSize

And moreover the built string is not appended with the terminating zero '\\0' .此外,构建的字符串没有附加终止零'\\0' As a result this statement结果这个说法

puts(result);

invokes undefined behavior.调用未定义的行为。

There is no need to create the variable length array无需创建变长数组

char result[maxSize];

just to output the concatenated string.只是为了输出连接的字符串。

The function can be declared and defined the following way as it is shown in the demonstrative program below.该函数可以通过以下方式声明和定义,如下面的演示程序所示。

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

The program output is程序输出是

hello

You have a couple of problems here.你在这里有几个问题。 result[resultSize + j] means you are effectively skipping over half the characters in result. result[resultSize + j]意味着你实际上跳过了结果中的一半以上的字符。 Secondly, if you copy the entire string, including the null character, puts will stop printing the result string at the end of the first word itself.其次,如果您复制整个字符串,包括空字符, puts将停止在第一个单词本身的末尾打印结果字符串。 So you need to skip copying the string terminator and put it in at the end of your whole concatenated string.因此,您需要跳过复制字符串终止符并将其放在整个连接字符串的末尾。

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

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

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