首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么这个程序不起作用?

为什么这个程序不起作用?
EN

Stack Overflow用户
提问于 2018-05-10 03:12:31
回答 2查看 108关注 0票数 0

当我在C编程语言上工作时,我想做一个小程序来修改以前的知识点。这就是这个程序,它似乎有一些问题。

这个程序应该从输入中收集信息,并以一种格式在文件"reg.txt“中打印出来。

但是,在输入第一行并按enter键后,程序就退出了,但是我不知道它到底出了什么问题。

代码语言:javascript
复制
#include <stdio.h>

int main()
{
    FILE *fp;
    struct profile
    {
        char *name;
        char *surname;
        int year;
        int month;
        int day;
    } people[10];
    int temp;
    int i = 0;
    char *line;


    fp = fopen("reg.txt", "a");
    while (fgets(line, 256, stdin)
    {
        sscanf(line, "%s %s %d/%d/%d", people[i].name, people[i].surname, &(people[i].year), &(people[i].month), &(people[i].day));
        ++i;
    }
    temp = i-1;

    for (i = 0; i <= temp; ++i)
        fprintf(fp, "NAME: %s %s\nBIRTHDAY: %d/%d/%d\n", people[i].name, people[i].surname, people[i].year, people[i].month, people[i].day);

    fclose(fp);
    return 0;
}

我接受了Ed Heal的建议,并且我的目标是检查'sscanf‘的返回值。奇怪的是,程序并没有真正到达“printf”部分。我想这个循环可能有问题吗?

代码语言:javascript
复制
#include <stdio.h>

int main()
{
    FILE *fp;
    void filecopy(FILE *, FILE *);
    struct profile
    {
        char *name;
        char *surname;
        int year;
        int month;
        int day;
    } people[10];
    int temp;
    int i = 0;
    char *line;
    int j;


    fp = fopen("reg.txt", "a");
    while (fgets(line, 256, stdin) != NULL)
    {
        j = sscanf(line, "%s %s %d/%d/%d", people[i].name, people[i].surname, &(people[i].year), &(people[i].month), &(people[i].day));
        ++i;
    }
    temp = i-1;

    //for (i = 0; i <= temp; ++i)
    //  fprintf(fp, "NAME: %s %s\nBIRTHDAY: %d/%d/%d\n", people[i].name, people[i].surname, people[i].year, people[i].month, people[i].day);

    printf("%d",j);
    fclose(fp);
    return 0;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-10 04:14:30

即使在确保line已经分配了内存之后,当sscanf尝试向people[0].namepeople[0].surname写入时,您的sscanf上也会出现分段错误,因为这些指针将是未定义的。

您需要静态或动态地为这些字符串分配内存(使用malloc)。

打印日志语句也有助于收集一些洞察力。

代码语言:javascript
复制
#include <stdio.h>

int main()
{
    FILE *fp;
    typedef struct
    {
        char name[64];
        char surname[64];
        int year;
        int month;
        int day;
    } profile;
    profile people[10];

    int temp;
    int i = 0;
    char line[512];

    printf("Starting profile line parser...\n");
    printf("Please enter up to 10 people in the format: (name surname year/month/day)\n");
    printf("Enter EOF to exit. (Linux: CTRL+D     Windows CTRL+Z)\n");
    fp = fopen("reg.txt", "a");
    while (gets(line) != NULL)
    {
        sscanf(line, "%63s %63s %d/%d/%d", people[i].name, people[i].surname, &(people[i].year), &(people[i].month), &(people[i].day));
        ++i;
    }
    printf("Processed %d lines.\n", i);
    temp = i-1;
    for (i = 0; i <= temp; ++i)
    {
        fprintf(fp, "NAME: %s %s\nBIRTHDAY: %d/%d/%d\n", people[i].name, people[i].surname, people[i].year, people[i].month, people[i].day);
    }

    fclose(fp);
    printf("Done with profile line parser...\n");
    return 0;
}

编辑:因为gets是不推荐的,这里有一个fget替代方案。关于gets的进一步阅读:Why is the gets function so dangerous that it should not be used?

编辑:还添加了chux的缓冲区溢出保护。关于用scanf:Read no more than size of string with scanf()防止缓冲区溢出的进一步解读

代码语言:javascript
复制
#include <stdio.h>

int main()
{
    FILE *fp;
    typedef struct
    {
        char name[64];
        char surname[64];
        int year;
        int month;
        int day;
    } profile;
    profile people[10];

    int temp;
    int i = 0;
    char line[512];

    printf("Starting profile line parser...\n");
    printf("Please enter up to 10 people in the format: (name surname year/month/day)\n");
    printf("Enter EOF to exit. (Linux: CTRL+D     Windows CTRL+Z)\n");
    fp = fopen("reg.txt", "a");
    while (fgets(line, 512, stdin) != NULL)
    {
        sscanf(line, "%63s %63s %d/%d/%d", people[i].name, people[i].surname, &(people[i].year), &(people[i].month), &(people[i].day));
        ++i;
    }
    printf("Processed %d lines.\n", i);
    temp = i-1;
    for (i = 0; i <= temp; ++i)
    {
        fprintf(fp, "NAME: %s %s\nBIRTHDAY: %d/%d/%d\n", people[i].name, people[i].surname, people[i].year, people[i].month, people[i].day);
    }
    printf("Done with profile line parser...\n");
    fclose(fp);
    return 0;
}
票数 1
EN

Stack Overflow用户

发布于 2018-05-10 03:28:32

在使用linegets之前,您需要分配内存。

代码语言:javascript
复制
#include <stdio.h>

int main()
{
    FILE *fp;
    struct profile
    {
        char *name;
        char *surname;
        int year;
        int month;
        int day;
    };
    struct profile people[10];
    int temp;
    int i = 0;
    char line[256]; //you can also do dynamic allocation by using malloc

    fp = fopen("reg.txt", "a");
   // while (gets(line) != NULL) //use fgets instead gets
    while( fgets(line, 256, stdin) ) //specify required buffer len
    {
        sscanf(line, "%s %s %d/%d/%d", people[i].name, people[i].surname, &(people[i].year), &(people[i].month), &(people[i].day));
        ++i;
    }
    temp = i-1;

    for (i = 0; i <= temp; ++i)
        fprintf(fp, "NAME: %s %s\nBIRTHDAY: %d/%d/%d\n", people[i].name, people[i].surname, people[i].year, people[i].month, people[i].day);

    fclose(fp);
    return 0;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50264916

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档