0
struct employee {
        int employeeId;
        double payrate;
        char *inputname;
    };



    int main (void){

        //remember the struct before employee

        struct employee davidB;
        fgets(davidB.inputname, 20, stdin);
        davidB.employeeId = 1;
        davidB.payrate = 45020.50;


        printf("The employees name is %s\n The employees id num is  %d\n The employees payrate is %f\n", davidB.inputname, davidB.employeeId, davidB.payrate);

        struct employee ericG;

        printf("Please enter employee name, id number, and payrate\n");

        scanf("%s", ericG.inputname);
        scanf("%d", &ericG.employeeId);
        scanf("%lf", &ericG.payrate);

        printf("The employees name is %s\n The employees id num is  %d\n The employees payrate is %f\n", ericG.inputname, ericG.employeeId, ericG.payrate);

        return 0;
    }

我的问题包括:

                          fgets(davidB.inputname, 20, stdin);  
                          scanf("%s", ericG.inputname);

为什么第一个有效,为什么第二个会导致堆栈溢出?此外,何时可以直接将“字符串”分配给指针,何时需要为预定义的 char 数组?

例如:

   const char *string = "Hey"; //works? so can't I do the same with the scanf above?
4

3 回答 3

1

您需要分配内存才能使用这些函数,否则会出现堆栈溢出,因为该指针 ( davidB.inputname) 指向垃圾。

一种选择是定义它,char inputname[21];但这仅适用于该fgets函数,因为您可以限制读取的字符数。但是,scanf除非您可以 100% 了解您要阅读的字符串的大小,否则您无能为力,因此最好避免使用它。

于 2013-01-28T23:56:34.587 回答
1

您还没有为`inputname. 所以两者都会调用未定义的行为。所以两者都不起作用,无论如何都不是合法的C。

但是当你像这样直接分配时:

const char *string = "Hey";

string仅指向字符串文字。所以那里不需要内存分配。

所以通过这种方式,可以直接赋值给struct成员:

    struct employee davidB;
    davidB.inputname = "Eric"; // Thiis is valid.
    davidB.employeeId = 1;
    davidB.payrate = 45020.50;

否则,您必须为以下内容动态分配内存inputname

    struct employee davidB;
    davidB.inputname = malloc(256);
    fgets(davidB.inputname, 256, stdin); 
    davidB.employeeId = 1;
    davidB.payrate = 45020.50;
于 2013-01-28T23:57:27.870 回答
1

一种方法有效,但另一种方法无效,这只是随机的运气。这两种方法都不正确,因为您没有为 inputname 分配任何内存来指向。因此,这些函数只是将数据输入到某个随机内存位置。

const char *string = "Hey" 之所以有效,是因为这是静态数据,编译器在某处为其分配空间。

于 2013-01-28T23:58:03.510 回答