【问题标题】:Saving string values from stdin into struct field将字符串值从标准输入保存到结构字段中
【发布时间】:2018-08-27 02:54:44
【问题描述】:

我试图在while 循环中从标准输入(我使用char *gets(char *str))分配值,但它似乎不起作用。我有七个automobile struct`,我希望在每次迭代中,我尝试填充的变量从 a1.marca 到 a2.marca 的输入变化。我试过这个策略,但它似乎不起作用。

    #include <stdio.h>
    #include <stdlib.h>
    
    struct automobile
    {
        char marca[15];
        char modello[20];
        char targa[7];
        unsigned cilindrata;
    } a1, a2, a3, a4, a5, a6, a7;
    
    int main()
    {
        int Nauto=7, a=0;
        char const id[3]={'a', '1', '\0'};
        a=1;
        while (Nauto>0)
        {
            printf ("Inserisci i dati della %d%c auto\n", a, 167);
            printf ("Marca: ");
            gets(id.marca);
            printf ("Modello: ");
            gets(id.modello);
            printf ("Targa: ");
            gets(id.targa);
            printf ("Cilindrata: ");
            scanf ("%d", &id.cilindrata);
            a++;
            Nauto--;
            id[2]=a;
        }
        return 0;
    }

【问题讨论】:

  • 永远不要使用gets。这是一个危险的函数,甚至已从 C 规范中删除。请改用fgets
  • 谢谢,但还有其他问题吗?
  • 至于你的问题,从1 != '1'开始。我建议你先看看例如this ASCII table(ASCII 是最常见的字符编码)。另外,您还记得数组索引是从零开始的吗?这意味着数组中的第二个元素具有索引1
  • 不要混用 fgets()fscanf()go4expert.com/articles/solution-using-scanf-fgets-c-t27148
  • 你的id变量不是结构体类型,你怎么能把它当结构体。另一件事是 const 限定的意思是你以后不能改变它的值。

标签: c struct


【解决方案1】:

您应该有一个汽车数组,然后在 while 循环中您可以索引该数组。 for 循环会比 while 循环更容易:

struct automobile
{
    char marca[15];
    char modello[20];
    char targa[7];
    unsigned cilindrata;
} a[6];

for (int i=0; i<6; i++)
{
    fgets(a[i].marca, sizeof(a[i].marca), stdin);
    // ....
}

注意使用fgets,它比gets 更安全,因为您可以指定要读取的字符数。

指定要读取的字符数的最安全方法是使用sizeof。这里需要sizeof(a[i].marca) 字符。编译器将用编译时的大小替换它,即使a[i] 看起来像运行时。这是最安全的,因为如果您以后决定更改 marca 的大小,此处会自动更改要读取的大小。

fgets 的规范说它最多可以读取n-1 字符,因此字符串的终止空字符将有空间。最后一个参数的含义我参考fgets的文档。仔细阅读以了解其行为。

【讨论】:

  • 谢谢,你能解释一下 fgets 的最后两个参数是什么吗?
【解决方案2】:

我明白了你想要做什么。在 C 中,分配静态结构并像那样使用它是不切实际的。相反,您可以动态分配它。下面是我正在运行的代码示例(我试图维护您的代码):

#include <stdio.h>
#include <stdlib.h>

#define maxNauto 7

typedef struct
{
    char marca[15];
    char modello[20];
    char targa[7];
    unsigned cilindrata;
} automobile;

int main()
{
    int Nauto=0, a=0;
    a=1;
    automobile** autos = (automobile**) malloc(maxNauto * sizeof(automobile*)); // Allocates an array of automobiles to
                                                                            // Support each index of an automobile struct
    while (Nauto < maxNauto)
    {
        autos[Nauto] = (automobile*) malloc(sizeof(automobile)); // Allocate each automobile struct

        printf ("Inserisci i dati della %d%c auto\n", a, 167);

        printf ("Marca: ");
        getc(stdin); // Gets the '\n' char from the stdin, so it's not detected as an input in fgets or scanf
        fgets(autos[Nauto]->marca, 15, stdin);
        printf ("Modello: ");
        fgets(autos[Nauto]->modello, 20, stdin);
        printf ("Targa: ");
        fgets(autos[Nauto]->targa, 7, stdin);
        printf ("Cilindrata: ");
        scanf ("%d", &(autos[Nauto]->cilindrata));

        a++;
        Nauto++;
    }
    return 0;
}

【讨论】:

  • 不需要先分配一个指针数组,然后分别分配每个struct automobile。此外,getc(stdin) 调用只会读取来自stdin 的第一个字符,它不会使后续的fgets()scanf() 调用忽略换行符。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-24
  • 1970-01-01
  • 2015-01-18
  • 1970-01-01
相关资源
最近更新 更多