【问题标题】:Segmentation Fault after reading in long长读后出现分段错误
【发布时间】:2014-04-02 23:19:49
【问题描述】:
#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. 为结构分配内存,并提示/读取有关结构的数据
  3. 编写 1 个将打印出该数据的函数

所以...以上是我的代码,我有几个问题:

    1234563按回车它卡在标准输入中并将其解析为scanf,因此将getchar()的工作放在一起。但是有没有办法避免这种情况一起发生?这在我的任何其他程序中从未发生过......
  1. 如您所见,我正在使用 fgets 来获取字符串,因为文件名可能包含空格,而 scanf 无法使用。但我的问题是,我是否必须将其存储在 temp 中,然后将其复制过来,或者我可以这样做: fgets(toUse->fileName, 100, 标准输入); 我假设不是,出于同样的原因,我不能使用它: toUse->fileName = "测试"; 那么我目前的做法是正确的,还是有更好的方法?

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

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

【问题讨论】:

    标签: c pointers struct scanf fgets


    【解决方案1】:

    应该是:

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

    或者:

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

    【讨论】:

      【解决方案2】:

      需要传入变量的地址:

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

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:
          1. 尝试 scanf("%c\n", ...) 让 scanf 等待返回字符

          2. fgets(toUse->fileName, 100, stdin);可以工作,toUse->fileName = "Test";不要因为“Test”是指向“Test”字符串的指针,而是toUse->fileName是一个缓冲区,可以直接fgets进去

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

            大小相同: scanf("%d", toUse->size);应该是 scanf("%d", &toUse->size);

          【讨论】:

          • 其他人发现的malloc大小也是一个需要修复的问题。
          猜你喜欢
          • 1970-01-01
          • 2017-09-18
          • 1970-01-01
          • 2020-04-04
          • 1970-01-01
          • 1970-01-01
          • 2020-03-24
          • 2019-06-13
          相关资源
          最近更新 更多