将字符串与固定大小的数组组合

Combining strings with fixed size arrays

让我们来看下面的示例代码,我将两个固定大小的数组连接在一起:

int main(void) {
    char first_name[20], last_name[20], full_name[40];
    puts("First Name?"); 
    fgets(first_name, 20, stdin);
    puts("Last Name?");  
    fgets(last_name, 20, stdin);
    strcat(full_name, first_name);
    strcat(full_name, " ");
    strcat(full_name, last_name);
    puts(full_name);
}

假设 first/last 个名称少于 20 个字符,这将产生如下输出:

Robert                        Diaz

这是因为 full_name 尚未初始化,还是由于 strcat 的工作原理?执行此操作的更好方法是什么?

您必须初始化 full_name[40]。使用此初始化:

char full_name[40] = {0};

不过,你会得到一个奇怪的输出:

Robert
 Diaz

请记住,fgets() 函数会在按下 Enter 键后留下一个换行符。因此,您需要用 [=16=] 或简单的零替换换行符。

if (fgets(first_name, 20, stdin) == NULL) {
    // incorrectly executed
    return 1;
}
first_name[strlen(first_name) - 1] = 0;

此后,您将不会再遇到任何问题。您应该得到类似的输出:

Robert Diaz

我认为 sprintf 会在这里服务 better/cleaner。

//strcat(full_name, first_name);
//strcat(full_name, " ");
//strcat(full_name, last_name);
snprintf(full_name, sizeof(full_name), "%s %s", first_name, last_name);

看看 man page of sprintf 如果你还没有。

对于初学者来说,该程序具有未定义的行为,因为数组 full_name 未初始化且不包含字符串。

char first_name[20], last_name[20], full_name[40];

因此您不能使用 strcat 将字符串附加到不存在的字符串。

另一个问题是函数fgets可以将换行符'\n'附加到读取的字符串。你应该删除它。

程序可以这样看

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

int main(void) 
{
    enum { N = 20 };
    char first_name[N], last_name[N], full_name[2 * N];
    
    puts( "First Name?" ); 

    fgets( first_name, N, stdin );
    first_name[ strcspn( first_name, "\n" )] = '[=11=]';
    
    puts( "Last Name?" ); 
    
    fgets( last_name, N, stdin );
    last_name[ strcspn( last_name, "\n" )] = '[=11=]';

    strcpy( full_name, first_name );
    strcat( full_name, " " );
    strcat( full_name, last_name );
    
    puts( full_name );
}

程序输出可能看起来像

First Name?
Robert
Last Name?
Disz
Robert Diaz