如何将字符串分配给 C 中的结构变量?

How to assign a string to struct variable in C?

I am unable to figure out how to assign a string to a struct variable using only <stdio.h> header file.

下面的代码给我一个错误,我无法修复它。

#include <stdio.h>
 struct Student
{
    char name[50];
};
int main()
{
   struct Student s1;
   printf("Enter studen's name:\n");
   scanf("%s",s1.name);
   printf("Name : \n",s1.name);
   s1.name={"Hussain"};
   printf("Name : \n",s1.name);
}

编译时出现如下错误:

test.c: In function 'main':
test.c:12:12: error: expected expression before '{' token
    s1.name={"Hussain"};
            ^

我试过用以下方式初始化它:
s1.name="Hussain";
但这也行不通。
我可以通过使用指针来避免这种情况,如下所示:

#include <stdio.h>
 struct Student
{
    char *name;
};
int main()
{
   struct Student s1;
   printf("Enter studen's name:\n");
   scanf("%s",s1.name);
   printf("Name : %s\n",s1.name);
   s1.name="Hussain";
   printf("Name : %s\n",s1.name);
}

此代码运行良好,没有错误。
但是我想知道我在数组上到底哪里做错了,这导致我的代码无法运行。

字符数组(和一般数组)不能直接赋值,只能初始化。要将字符串写入字符数组,请使用 strcpy.

strcpy(s1.name, "Hussain");

后面的代码,其中 name 成员是一个指针,适用于赋值,因为指针被分配了字符串常量开头的起始地址。另请注意,在这种情况下您不能(至少现在不能)使用 strcpy 因为 s1.name 没有指向任何地方。您首先需要使用 malloc 分配内存,或者使用 strdup 同时执行这两个步骤。同样出于这个原因,在分配内存之前,您还不能使用 scanf

如果您不允许使用 string.h 中的函数,那么您需要一次一个地将字符写入数组,然后在末尾写入一个终止空字节。

数组没有赋值运算符。所以这些赋值语句

s1.name = { "Hussain" };
s1.name = "Hussain";

无效。

您可以使用标准 C 字符串函数 strcpy 将字符串文字的元素复制到数组 s1.name 中,例如

#include <string.h>

//...

strcpy( s1.name, "Hussain" );

如果您可能不会使用标准字符串函数,那么您需要编写一个循环,例如

const char *p = "Hussain";

for ( char *t = s1.name; ( *t++ = *p++ ) != '[=12=]'; );

for ( char *t = s1.name, *p = "Hussain"; ( *t++ = *p++ ) != '[=13=]'; );

注意第二个你的程序有未定义的行为。指针 s1.name 未初始化,未指向数组类型的有效对象。因此,此代码片段中 scanf 的调用会调用未定义的行为。

struct Student s1;
printf("Enter studen's name:\n");
scanf("%s",s1.name);

如果你不能使用<string.h>,那么你必须实现你自己的strcpy()版本:

void copystring(char *dest, const char *src)
{
    const char *p = src;
    while (*p) {
        *dest = *p;
        p++;
        dest++;
    }
    *dest = '[=10=]'; // Null-terminate string (as pointed by @Ted)
}

确保 dest 有足够的 space 容纳 src

此外,请避免在您的代码中使用 scanf()。使用 fgets() 作为替代。

编辑: 正如 Jabberwocky 所指出的,fgets() 留下 \n 在字符串中读取。但是由于不允许使用 <string.h>,您必须实现自己的功能以将其替换为 null-terminator:

int findchar(const char *str, char c)
{
    int pos;
    for (pos = 0; str[pos]; ++pos)
        if (str[pos] == c)
            return pos;
    
    return -1;
}

您可以像这样使用它:

char str[100];
if (!fgets(str, sizeof str, stdin)) {
    // fgets() failed. Do something.
} else {
    int nwln = findchar(str, '\n');
    if (nwln == -1) {
        // You probably entered more than 100 characters
        // because \n couldn't be found.
    } else {
        str[nwln] = '[=12=]';
    }
}