C 数组和指针的分段错误
我有一个分割错误…我不确定是什么原因造成的。另外,在将成员pname传递到函数get_names时,我是否正确地执行了此操作,或者是否有更好的方法执行此操作C 数组和指针的分段错误,c,segmentation-fault,C,Segmentation Fault,我有一个分割错误…我不确定是什么原因造成的。另外,在将成员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[MA
#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;
}
}
#包括
#定义最大名称20
#定义MAX_PLAYRS 16
类型定义结构{
char pname[最大名称];
整数运行;
查你是怎么出来的;
}小组;;
团队球员[最大球员];
球队球员[最大球员];
void get_名称(整数计数,字符*str);
内部主(空){
int i;
对于(i=0;i
找一个调试器来告诉你哪里出了问题。在启用调试的情况下编译代码(请参阅编译器的手册页),并运行如下操作:
gdb a.out core
然后您应该能够看到哪一行进行了代码核心转储。如果安装了intle编译器,也可以使用idb。这当然是在尼克斯。如果您正在谈论windows,请使用VS调试器
此外,不要使用
fscanf
,因为它不安全。改用fgets
。在代码不变的情况下,如果文件无法正确打开(即由于权限原因无法读取,或者根本不存在),则会出现分段错误
下面是函数的修改版本get\u names()
:
这仍然会读取名字16次,但它会告诉您为什么它无法打开文件。要从文件中读取下一个名称(而不是重复读取第一个名称),请改为在main()
函数中打开(并关闭)该文件
此外,您还可以像这样调用get_names()
:
get_names(i, player[i].pname);
不需要做你正在做的事
最后,我希望
teamnames.rtf
文件实际上不是一个rtf文件,而是一个简单的文本文件,每行都有一个名称。问题来自这一行:
get_names(i, &(*player[i].pname));
如果您正在从另一种语言转换,那么理解指针和取消引用是学习C语言的最大调整之一。你做错了,我认为你应该找一本关于这个主题的教程。尝试作为起点。有很多奇怪的事情。第一件事是,名称似乎在一个文件中,但您所做的是在for循环的每一次迭代中,您调用
get_names
,它会再次打开文件,即转到文件的开头,并反复读取相同的名称
如果你关闭了文件。由于您尚未关闭该文件,因此该文件已打开,并且您一直在重新打开它(这可能是问题的原因)
另一件事是,你怎么能
if (status == EOF) {
count = MAX_PLAYRS;
}
给你当前的计数?不管文件中的玩家数量如何,您只需将其设置为MAX\u 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;
}
}
#包括
#定义最大名称20
#定义MAX_PLAYRS 16
类型定义结构{
char pname[最大名称];
整数运行;
查你是怎么出来的;
}小组;;
团队球员[最大球员];
球队球员[最大球员];
void get_名称(整数计数、字符*str、文件*inp);
内部主(空){
文件*inp;
int i;
整数计数;
inp=fopen(“teamnames.rtf”,“r”);
对于(i=0;i
以下是我将如何更简洁地做到这一点:
#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);
}
}
#包括
#定义最大名称20
#定义MAX_PLAYRS 16
类型定义结构{
char pname[最大名称];
整数运行;
查你是怎么出来的;
}小组;;
团队球员[最大球员];
球队球员[最大球员];
int get_名称(团队*Team);
内部主(空){
获取您的姓名(玩家);
}
int get_名称(团队){
int i=0;
文件*inp;
inp=fopen(“teamnames.rtf”,“r”);
而(i
请注意此解决方案不关心
fscanf
的问题、检查数组边界等,但这会让您了解如何不复制粘贴代码。对布局表示歉意,这也是堆栈溢出的新问题。这是一种反向缩进布局吗?缩进块更适合于e左边比右边多o.0您将只读取文件中的第一个字符串,状态应为int,fscanf应为%19s
。。。
#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);
}
}