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

C 将字符串与固定大小数组组合,c,newline,c-strings,fgets,strcat,C,Newline,C Strings,Fgets,Strcat,让我们以下面的示例代码为例,其中我将两个固定大小的数组连接在一起: 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); s

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

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);
}
假设名字/姓氏少于20个字符,这将产生如下输出:

Robert                        Diaz

这是因为
全名
尚未初始化,还是因为
strcat
的工作方式?有什么更好的方法可以做到这一点?

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

char full_name[40] = {0};
尽管如此,您仍会得到一个奇怪的输出:

Robert
 Diaz
请记住,
fgets()
函数在按下Enter键后会留下一个换行符。因此,您需要将换行符替换为
\0
,或者简单地替换为零

if (fgets(first_name, 20, stdin) == NULL) {
    // incorrectly executed
    return 1;
}
first_name[strlen(first_name) - 1] = 0;
在此之后,您将不再遇到任何问题。您应该得到类似的输出:

Robert Diaz

我认为
sprintf
在这里会更好/更干净

//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);

如果没有,请查看。

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

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" )] = '\0';
    
    puts( "Last Name?" ); 
    
    fgets( last_name, N, stdin );
    last_name[ strcspn( last_name, "\n" )] = '\0';

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

strcat(全名、名)
这是因为
全名
从未初始化过。更好的方法是初始化它,或者用strcpy替换第一个strcat,或者用sprintf@dxiv一次完成——初始化数组归零的正确方法是什么<代码>字符全名={0}?@dxiv同样,如果某个东西没有初始化,
strcat
从哪里开始?它是否将第一个
\0
替换为那里的新字符串?是的,
char full\u name={0}将使整个数组归零。或者,出于strcat
目的,只需将nul字符放在全名[0]='\0'的前面也可以。至于数组未初始化时会发生什么,因此推测某些特定事件发生的原因是毫无意义的,因为任何事情都可能发生。当然,如果输入不完全符合
fgets()的要求,您不必添加
if
语句吗
因此最后一个字符不是
\n
?@David542是的,检查这些函数的返回值总是被认为是好的。为什么
strcspn
而不是
strchr
,哪一个更快?@Lundin在最后一种情况下,您需要引入一个变量,调用strchr后检查是否等于NULL。在
strcspn
中会有更多的分支和临时变量。实际上,
strcspn
的一些C库实现只是在循环中调用
strchr
。其他人使用大量的查找表。
First Name?
Robert
Last Name?
Disz
Robert Diaz