简体   繁体   English

为什么该程序不起作用?

[英]Why doesn't this program work?

When I was working on the C Programming Language , I wanted to do a little program to revise these previous knowledge points. 当我使用C编程语言时 ,我想做一个小程序来修改这些以前的知识点。 And this is the program which it seems there are some problems with it. 这是一个似乎有问题的程序。

This program is supposed to collect information from input and print it in the file "reg.txt" in a format. 该程序应该从输入中收集信息,并以格式将其打印在“ reg.txt”文件中。

However, after typing the first line and press the enter, the program quits, but I can't figure it out what's wrong with it. 但是,在键入第一行并按Enter键之后,该程序退出,但是我无法弄清楚它出了什么问题。

#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;
}

I've taken Ed Heal 's advice and I was aim to check the return value of 'sscanf'. 我接受了Ed Heal的建议,目的是检查'sscanf'的返回值。 What's strange is that the program doesn't really reach the 'printf' part. 奇怪的是该程序并没有真正到达“ printf”部分。 I thought may there are some problems with the loop? 我以为循环可能存在一些问题?

#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;
}

Even after making sure line has allocated memory, you should be getting a segfault on your sscanf when it tries to write to people[0].name and people[0].surname because those pointers will be undefined. 即使在确定line已分配内存之后,当sscanf尝试写入people[0].namepeople[0].surname时,也应该在它的段上出现段people[0].surname因为这些指针将是未定义的。

You need to allocate memory for these strings, either statically or dynamically (with malloc). 您需要为这些字符串静态或动态分配内存(使用malloc)。

Printing log statements can also help quite a bit to gather some insight. 打印日志语句也可以帮助您收集一些见解。

#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;
}

EDIT: Because gets is deprecated, here is a fgets alternative. 编辑:因为不赞成使用gets,所以这里是fgets的替代方案。 Further reading on gets: Why is the gets function so dangerous that it should not be used? 关于gets的进一步阅读: 为什么gets函数如此危险,以至于不应该使用它?

EDIT: Also adding chux's buffer overflow protection. 编辑:还添加了chux的缓冲区溢出保护。 Further reading on preventing buffer overruns with scanf: Read no more than size of string with scanf() 有关使用scanf防止缓冲区溢出的更多信息使用scanf()读取的字符串大小不超过

#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;
}

You need to allocate memory before you use line with gets 您需要在使用前分配内存linegets

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM