我有分段错误...我不确定是什么导致它。另外,当将成员pname传递给函数get_names时,我是否正确地执行此操作,或者有更好的方法吗?
#include <stdio.h>
#define MAX_NAME 20
#define MAX_PLAYRS 16
typedef struct {
char pname[MAX_NAME];
int runs;
char how_out;
} Team_t;
Team_t player[MAX_PLAYRS];
Team_t *player_ptr[MAX_PLAYRS];
void get_names (int count, char *str);
int main (void) {
int i;
for (i = 0; i < MAX_PLAYRS; i++) {
get_names(i, &(*player[i].pname));
printf("Player: %s\n", player[i].pname);
}
}
void get_names (int count, char *str) {
FILE *inp;
char status;
inp = fopen("teamnames.rtf", "r");
status = fscanf(inp, "%s", str);
if (status == EOF) {
count = MAX_PLAYRS;
}
}
答案 0 :(得分:1)
如果您的代码未更改,如果文件无法正确打开(即由于权限而无法读取,或者根本不存在),则会出现分段错误。
以下是您的函数get_names()
的修改版本:
void get_names(int count, char *str)
{
FILE *inp;
inp = fopen("teamnames.rtf", "r");
if (inp == NULL) {
perror("Failed");
return;
}
fgets(str, MAX_NAME, inp);
fclose(inp);
}
这仍然会读取16次名字,但它会告诉你为什么它没有设法打开文件。要从文件中读取下一个名称(而不是重复使用名字),请在main()
函数中打开(并关闭)该文件。
另外,您也可以这样称呼get_names()
:
get_names(i, player[i].pname);
无需执行&(*...)
您正在做的事情。
最后,我希望teamnames.rtf
文件实际上不是RTF文件,而是一个简单的文本文件,每行都有一个名称。
答案 1 :(得分:0)
获取调试器以告诉您出了什么问题。在启用调试的情况下编译代码(参见编译器的手册页)并运行如下代码:
gdb a.out core
然后你应该能够看到代码核心转储的哪一行。如果安装了intle编译器,也可以使用idb。当然,这是在* nix上。如果您正在谈论Windows,请使用VS调试器。
此外, NOT 使用fscanf
,因为它不安全。请改用fgets
。
答案 2 :(得分:0)
问题来自这一行:
get_names(i, &(*player[i].pname));
如果您从另一种语言切换,了解指针和解除引用是学习C的最大调整之一。你做错了,我认为你应该找一个关于这个主题的教程。尝试http://www.cplusplus.com/doc/tutorial/pointers/作为起点。
答案 3 :(得分:0)
有许多奇怪的事情。首先,似乎名称在文件中,但你正在做的是在for循环的每次迭代中,你调用get_names
再次打开文件,即转到文件的开头你一遍又一遍地读同一个名字。
那就是你关闭了文件。由于您尚未关闭文件,因此该文件已经打开,您可以继续重新打开它(这可能是导致问题的原因)
另一件事是,怎么可以
if (status == EOF) {
count = MAX_PLAYRS;
}
给你当前的数量?无论文件中的玩家数量如何,您只需将其设置为MAX_PLAYERS
。
另一件事是count
是函数的输入而不是指针,所以设置它不会改变函数外的值(这是我想你想要的)。
以下是对代码进行最少更改的方法:
#include <stdio.h>
#define MAX_NAME 20
#define MAX_PLAYRS 16
typedef struct {
char pname[MAX_NAME];
int runs;
char how_out;
} Team_t;
Team_t player[MAX_PLAYRS];
Team_t *player_ptr[MAX_PLAYRS];
void get_names (int count, char *str, FILE *inp);
int main (void) {
FILE *inp;
int i;
int count;
inp = fopen("teamnames.rtf", "r");
for (i = 0; i < MAX_PLAYRS; i++) {
get_names(&count, player[i].pname, inp);
printf("Player: %s\n", player[i].pname);
}
}
void get_names (int *count, char *str) {
char status;
status = fscanf(inp, "%s", str);
if (status == EOF) {
*count = MAX_PLAYRS;
}
}
以下是我将如何更简洁地做到这一点:
#include <stdio.h>
#define MAX_NAME 20
#define MAX_PLAYRS 16
typedef struct {
char pname[MAX_NAME];
int runs;
char how_out;
} Team_t;
Team_t player[MAX_PLAYRS];
Team_t *player_ptr[MAX_PLAYRS];
int get_names (Team_t *team);
int main (void) {
get_names(player);
}
int get_names (Team_t *team) {
int i = 0;
FILE *inp;
inp = fopen("teamnames.rtf", "r");
while (i < MAX_PLAYRS && !feof(inp) {
fscanf(inp, "%s", team[i].pname);
printf("Player: %s\n", player[i].pname);
}
}
注意,fscanf
的问题,检查数组边界等不是这个解决方案的关注点,但这相当于让你知道什么不是你的代码复制 - 粘贴。