2011-09-27 138 views
0

我有一个分段错误...我不知道是什么导致它。另外,当将成员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

道歉的布局,新的堆栈溢出以及 –

+2

这是一些反向缩进布局?缩进块比左侧更靠近o.0 – orlp

+0

段错误在哪里? – Chowlett

回答

0

问题来源于此行:

get_names(i, &(*player[i].pname)); 

了解指针和非关联化是最大的调整,以学习C,如果你是从其他语言转换的一个。你做错了,我认为你应该寻找关于这个主题的教程。以http://www.cplusplus.com/doc/tutorial/pointers/作为起点。

0

得到一个调试器,告诉你什么是错的。编译启用调试代码(请参阅您的编译器,你的男人页),然后运行是这样的:

gdb a.out core 

那么你应该能够看到这行做的代码核心转储。如果你安装了编译器,你也可以使用idb。这当然是在* nix上。如果你在说窗口,使用VS调试器。

另外做不是使用fscanf因为它是不安全的。改为使用fgets

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文件,而是一个简单的文本文件,每行都有一个名称。

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问题,检查数组边界等并不是这个解决方案的关注点,但是这样可以让你知道不需要代码来复制粘贴的想法。