为什么这个程序不起作用?
Why doesn't this program work?
我在做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' 的 return 值。奇怪的是程序并没有真正到达'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;
}
在使用 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;
}
即使在确保 line
已分配内存之后,当它尝试写入 people[0].name
和 people[0].surname
时,您应该会在 sscanf
上遇到段错误,因为那些指针将是未定义的。
您需要为这些字符串分配内存,静态或动态(使用 malloc)。
打印日志语句也有助于收集一些见解。
#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 已被弃用,这里有一个 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()
#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;
}
我在做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' 的 return 值。奇怪的是程序并没有真正到达'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;
}
在使用 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;
}
即使在确保 line
已分配内存之后,当它尝试写入 people[0].name
和 people[0].surname
时,您应该会在 sscanf
上遇到段错误,因为那些指针将是未定义的。
您需要为这些字符串分配内存,静态或动态(使用 malloc)。
打印日志语句也有助于收集一些见解。
#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 已被弃用,这里有一个 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()
#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;
}