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

时间:2018-05-10 03:12:31

标签: c scanf fgets gets

当我使用 C编程语言时,我想做一个小程序来修改这些以前的知识点。这个程序看起来似乎存在一些问题。

该程序应该从输入中收集信息并以格式在“reg.txt”文件中打印。

然而,在输入第一行并按回车键后,程序退出,但我无法弄清楚它有什么问题。

#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'部分。我想可能循环有问题吗?

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

2 个答案:

答案 0 :(得分:1)

即使在确保sscanf分配了内存之后,当people[0].name尝试写入people[0].surname#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; } 时,您应该在#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; } 上遇到段错误,因为这些指针会未定义。

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

打印日志语句也可以帮助我们收集一些见解。

template <typename Cont>
auto my_sort(Cont& cont)
-> decltype(cont[42], // Indexable
            void(), // That void to avoid evil overload of operator comma
            std::declval<Cont::Element>() < std::declval<Cont::Element>(), // Comparable
            void()) // That final void for the return type of sort
{
    // do sorting work
}

编辑:因为不推荐使用gets,所以这里有一个fgets替代方案。 进一步阅读获取:Why is the gets function so dangerous that it should not be used?

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

decltype

答案 1 :(得分:0)

line

使用gets之前,您需要分配内存
#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;
}