长时间阅读后的分段错误

时间:2014-03-01 21:53:42

标签: c pointers struct scanf fgets

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

struct fileData
{
        char fileName[100];
        int size;
        char type;
        long timestamp;
};

void print(struct fileData *myFile);

int main(void)
{
        struct fileData *toUse = malloc(sizeof(toUse));
        char temp[100] = {0};

        printf("Enter the type:");
        getchar();
        scanf("%c", toUse->type);
        getchar();
        printf("Enter the filename:");
        fgets(temp, 100, stdin);
        strcpy(toUse->fileName, temp);
        printf("Enter the access time:");
        scanf("%lf", toUse->timestamp);
        printf("Enter the size:");
        scanf("%d", toUse->size);

        print(toUse);
        free(toUse);
}

void print(struct fileData *myFile)
{
        printf("Filename: %s - Size: %d - Type: [%c] - Accessed @ %ld\n", myFile->fileName, myFile->size, myFile->type, myFile->timestamp);
}

好的,这就是程序应该做的事情:

  1. 为文件数据创建一个结构(必须在main中使用指针)
  2. 结构的malloc内存,以及有关结构的数据的提示/读取
  3. 编写将打印出该数据的1函数
  4. 所以...上面是我的代码,我有几个问题:

    1. 你可能会注意到我有一些getchar(),原因是因为无论出于什么原因我运行./a.out它总是跳过我猜的第一个scanf,因为当我按下输入它卡在stdin中并解析为scanf,所以把getchar()的工作...但是反正是为了避免这种情况一起发生?这从未在我的任何其他程序中发生......

    2. 正如您所看到的,我正在使用fgets来获取字符串,因为文件名可能包含空格,而scanf不能使用。但我的问题是,我是否必须将其存储在临时文件中然后将其复制或者我可以这样做: fgets(toUse-&gt; fileName,100,stdin); 我假设没有,出于同样的原因我不能用这个: toUse-&gt; fileName =“Test”; 那么这正是我目前正在做的方式,还是有更好的方法?

    3. 现在对于使我的程序失败的实际问题,在“输入访问时间:”中的下一个读数,它将让我输入一个数字但是只要我按下输入我就会得到一个Seg Fault ...所以为什么?是因为我使用的是%lf吗?这是完全不同的东西吗?我应该在scanf中使用%l吗? [当我这样做时,它会跳过这个问题..我假设出于同样的原因它会跳过其他的......处理输入的东西]。那么这就是它,输入我输入长“1234567890”导致它出错或我做错了什么?

    4. 任何回答的问题都会有所帮助,谢谢!

4 个答案:

答案 0 :(得分:1)

  1. 尝试scanf(“%c \ n”,...),以便scanf等待返回字符

  2. fgets(toUse-&gt; fileName,100,stdin);可以工作,使用&gt; fileName =“测试”;不要因为“Test”是指向“Test”字符串的指针,但是toUse-&gt; fileName是一个缓冲区,你可以直接在其中输入

  3. %lf是一种长浮点格式。在scanf中尝试%ld。然后你需要给scanf一个写入的地址,使用scanf(“%ld”,&amp; toUse-&gt; timestamp);

    大小相同:scanf(“%d”,toUse-&gt; size);应该是scanf(“%d”,&amp; toUse-&gt; size);

答案 1 :(得分:0)

应该是:

struct fileData *toUse = malloc(sizeof *toUse);
//                                     ^^^^^^

可替换地:

struct fileData *toUse = malloc(sizeof(struct fileData));

答案 2 :(得分:0)

您需要传递变量的地址:

scanf("%lf", &(toUse->timestamp));
printf("Enter the size:");
scanf("%d", &(toUse->size));

filename是一个char数组,因此对(filename ,,,)的引用实际上是地址。其他值是标量,而不是数组。

答案 3 :(得分:0)

因为你没有分配足够的空间。

SizeOf(toUse) =地址的大小,在32位机器上= 4个字节,但显然结构的大小超过100个字节。

因此,您需要分配structure fileDate的大小。

变化:

struct fileData *toUse = malloc(sizeof(toUse));

到:

struct fileData *toUse = malloc(sizeof(struct fileData));

并避免编译器警告不兼容的指针类型:

struct fileData *toUse = (struct fileData *) malloc(sizeof(struct fileData));