简体   繁体   English

无法连接两个字符串

[英]Unable to concatenate two strings

I was practicing on the topics of string.我正在练习字符串的主题。 I am trying to concatenate two strings without using the strcat() function available in C.我试图在不使用 C 中可用的strcat() function 的情况下连接两个字符串。

This is the code that I came up with:这是我想出的代码:

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>

int string_length();
void concatenate();

int main(void) {
    char str[] = "Hello there";
    char str2[] = "How are you";
    char result[100];
    int length;

    length = string_length(str);

    printf("%d\n", length);
    concatenate(result, str, str2);
}

//Function which counts the number of characters of the string
int string_length(char str[]) {
    int i = 0;
    while (str[i] != '\0') {
        i++;
    }
    return i;
}

//Function to concatenate the two strings
void concatenate(char result[], char str[], char str2[]) {
    int i = 0;
    while (str[i] != '\0') {
        result[i] = str[i];
        ++i;
    }
    int j = i + 2, k = 0;
    while (str2[k] != '\0') {
        result[j] = str2[k];
        k++;
        j++;
    }
    printf("%s\n", result);
}

When I ran this code, this is what I get as the output -当我运行这段代码时,这就是我得到的 output -

    11
    Hello there

The concatenation function is not working properly as output should be-串联 function 不能正常工作,因为 output 应该是-

    11
    Hello there How are you

I used the debugger and found that loops are working fine and as per the counter variable, The two strings should get concatenated.我使用了调试器,发现循环工作正常,并且根据计数器变量,这两个字符串应该连接起来。

There are multiple problems in your code:您的代码中存在多个问题:

  • in your concatenation function, you initialize j to i + 2 , whereas you should just use j = i as the first character of the second string should come just after the last character of the first and i was incremented after each character copied from str .在您的连接 function 中,您将j初始化为i + 2 ,而您应该只使用j = i作为第二个字符串的第一个字符应该紧跟在第一个字符串的最后一个字符之后并且i在从str复制的每个字符之后递增。 Note that you can just use i , there is no need for j .请注意,您可以只使用i ,不需要j
  • you must set the null terminator at the end of result .您必须在result末尾设置 null 终止符。 You can set at with result[j] = '\0';您可以设置为result[j] = '\0';
  • you should output the concatenated string in main instead of concatenate() .您应该在main中连接字符串而不是concatenate()
  • the prototypes of string_length() and concatenate() should include the argument types. string_length()concatenate()的原型应该包括参数类型。

Also note that you should use size_t for the index types.另请注意,您应该使用size_t作为索引类型。

Here is a modified version:这是修改后的版本:

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

size_t string_length(const char *s);
void concatenate(char *result, const char *str, const char *str2);

int main(void) {
    char str[] = "Hello there";
    char str2[] = "How are you";
    char result[100];
    size_t length;

    length = string_length(str);

    printf("%zu\n", length);
    concatenate(result, str, str2);
    printf("%s\n", result);  // shows Hello thereHow are you
    concatenate(result, "abc", "def");
    printf("%s\n", result);  // shows abcdef
    return 0;
}

//Function which counts the number of characters of the string
size_t string_length(const char *s) {
    size_t i = 0;
    while (str[i] != '\0') {
        i++;
    }
    return i;
}

//Function to concatenate the two strings
void concatenate(char *result, const char *str, const char *str2) {
    size_t i = 0;
    while (str[i] != '\0') {
        result[i] = str[i];
        ++i;
    }
    size_t k = 0;
    while (str2[k] != '\0') {
        result[i] = str2[k];
        k++;
        i++;
    }
    result[i] = '\0';
}

Here is an alternative approach, using pointer arithmetics:这是另一种方法,使用指针算法:

//Function to concatenate the two strings
void concatenate(char *result, const char *str, const char *str2) {
    // copy the bytes from str, including the null terminator
    while ((*result = *str++) != '\0')
        result++;

    // copy the bytes from str2, including the null terminator
    while ((*result = *str2++) != '\0')
        result++;
}

Problem lies in the fact that your result is empty (hence only 0s in it).问题在于您的结果为空(因此其中只有 0)。 When you skip indexes at line 38, you have a null terminator in your string that stops the reading from printf. You have to add manually a space if you do not want this comportment.当您跳过第 38 行的索引时,您的字符串中有一个 null 终止符,它会停止从 printf 读取。如果您不想要此行为,则必须手动添加一个空格。 Add a line after your first while result[i] = ' ';在你的第一个 while result[i] = ' ';之后添加一行and you should have your expected result.你应该有你预期的结果。

However, as it has been said, you do not have to skip 2 spaces with j.但是,如前所述,您不必使用 j 跳过 2 个空格。 Only one suffices.只有一个就够了。

Because you skip two elements of the result array, it will look something like this after the second loop:因为您跳过了结果数组的两个元素,所以在第二个循环之后它看起来像这样:

           +---+---+-----+---+---+---+---+---+---+---+----
Index    : | 0 | 1 | ... | 9 | 10| 11| 12| 13| 14| 15| ...
Character: | H | e | ... | r | e | ? | ? | H | o | w | ...
           +---+---+-----+---+---+---+---+---+---+---+----

At index 11 and 12 there will be two unknown characters.在索引1112处将有两个未知字符。

If you want to add a space you need to explicitly add it.如果你想添加一个空格,你需要明确地添加它。 And I recommend you keep the same i variable as the result array index both when adding the space and in the second loop:我建议您在添加空格时和在第二个循环中都保留与result数组索引相同的i变量:

// Needs to be define here since it's reused later
unsigned i;

// Copy the first string
for (i = 0; str[i] != '\0'; ++i) {
    result[i] = str[i];
}

// The index i will be right after the last character of the first string
// Add the space there
result[i] = ' ';

// Increase i to the first position of the second string
++i;

// Then copy the second string
for (unsigned k = 0; str2[k] != '\0'; ++k, ++i) {
    result[i] = str2[k];
}

// Now add the string null terminator
result[i] = '\0';

After this result[11] will be a space, and directly following it (starting at result[12] ) will be the second string.在此result[11]之后将是一个空格,紧随其后(从result[12]开始)将是第二个字符串。

Long worded explanations are usually difficult to follow because SO answers are typed (and edited and re-edited), and it is difficult to know what refers to which.措辞冗长的解释通常很难理解,因为 SO 答案是打字的(以及编辑和重新编辑的),而且很难知道什么指的是什么。

The very first comment response from @pmg tried to draw attention to some strange "index math". @pmg 的第一个评论回复试图引起人们对一些奇怪的“索引数学”的注意。 You may have imagined that if you 'skipped ahead two' there would magically be an ASCII space there to be printed... Wishes, eh?您可能已经想象过,如果您“向前跳过两个”,那里会神奇地出现一个 ASCII 空间来打印……祝愿,嗯?

Here's a "code dump" that improves on what you have written.这是一个改进您所写内容的“代码转储”。 By following it, line by line, you may see how it achieves the objective.通过逐行跟踪它,您可能会看到它是如何实现目标的。

// notice these (small) functions just get the job done with short variable names
#include <stdio.h> // don't include headers you don't use

// a function DEFINED is a function DECLARED. no prototypes necessary
int string_length( char str[] ) {
    int i = 0;
    while( str[i] ) i++;
    return i;
}

void concatenate( char *dst, char *s1, char *s2 ) {
    while( ( *dst = *s1 ) != '\0') { dst++; s1++; }

    *dst++ = ' '; // padding space inserted

    while( ( *dst++ = *s2++ ) != '\0') { }
}

int main( void ) {
    char str1[] = "Hello there!";
    char str2[] = "How are you?";

    int length = string_length( str1 );
    printf( "'%s' length = %d\n", str1, length );

    char result[100]; // define variables when/where they are used
    concatenate( result, str1, str2 );
    printf( "%s\n", result );

    return 0;
}
'Hello there!' length = 12
Hello there! How are you?

If you're willing to move on from the length function, and start to return useful pointers from your functions, you can have your own versions of two standard library functions (without some of their more advanced features that you'll come to understand in time.)如果你愿意从长度 function 开始,并开始从你的函数返回有用的指针,你可以拥有你自己版本的两个标准库函数(没有它们的一些更高级的特性,你将在时间。)

#include <stdio.h>

char *string_copy( char *dst, char *s ) {
    for( char *p = dst; ( *p++ = *s++ ) != '\0'; ) { }
    return dst;
}

char *string_cat( char *dst, char *s ) {
    char *p = dst;
    while( *p ) p++;
    while( ( *p++ = *s++ ) != '\0') { }
    return dst;
}

int main( void ) {
    char result[100], str1[] = "Hello there!", str2[] = "How are you?";
    
    printf( "%s\n", string_cat( string_cat( string_copy( result, str1 ), " "), str2 ) );

    return 0;
}

The output is as expected. output 符合预期。

Hello there! How are you?

The reason they are called functions is that they take one or more values , do something with them, and return something useful.它们被称为函数的原因是它们接受一个或多个,用它们做一些事情,并返回一些有用的东西。 (Think of trigonometry functions like sin that takes an angle and returns its y-axis offset on a unit-circle. (想想像sin这样的三角函数,它取一个角度并返回它在单位圆上的 y 轴偏移量。

The functions and parameters in the last example have been nested to build up to the desired result.)上一个示例中的函数参数嵌套以构建所需的结果。)

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

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