该程序将按字母顺序从文本创建链接列表 它区分大小写,它将消除标记。
当我运行程序时,它会产生分段错误。我无法找到问题所在。我添加了printf()
以便找到错误,但我不能。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct NODE {
char *word;
int count;
struct NODE *next;
}NODE;
char *get_word(FILE *fp){
printf("getWord");
char *str = (char*)malloc(sizeof(char)*100);
char c;
do {
c = fgetc(fp);
if (c == EOF)
return 0;
} while (!isalpha(c));
do {
printf("getWord");
*str++ = tolower(c);
c = fgetc(fp);
printf("Word");
} while (isalpha(c));
return str;
}
void insert(NODE* sortedList, char *word) {
printf("INSERT ");
char *str = (char*)malloc(sizeof(char)*100);
if (sortedList == NULL || word < sortedList->word) {
NODE *ekle;
ekle=(NODE*)malloc(sizeof(NODE));
strcpy(ekle->word,word);
ekle->count = 1;
ekle->next = sortedList;
sortedList = ekle;
}
else {
//
NODE *current = sortedList->next;
NODE *pre = sortedList;
while (current != NULL && word > current->word) {
pre = current;
current = current->next;
}
if (current != NULL && word == current->word) {
(current->count)++;
}
else {
NODE *ekle;
ekle=(NODE*)malloc(sizeof(NODE));
strcpy(ekle->word,word);
ekle->count = 1;
ekle->next = current;
pre->next = ekle;
}
}
}
void createList(FILE* fp,NODE *n) {
printf("CREATELIST ");
char *word;
strcpy(word,get_word(fp));
puts(word);
while (strcmp(word,"")) {
printf("Create_LİST2");
insert(n,word);
word = get_word(fp);
}
}
NODE *head;
int main(){
NODE *list=NULL;;
FILE *fp;
fp=fopen( "text.txt", "r" );
head=list;
while(!feof(fp)){
createList(fp,list);
}
while(list->next != NULL){
printf("%s", list->word);
}
return 0;
}
答案 0 :(得分:3)
一个主要问题是这一行
*str++ = tolower(c);
这会更改指针str
,因此当您从函数返回str
时,它实际上将指向字符串。顺便说一句,你不会终止的字符串。
另一个主要问题是这些问题:
NODE *ekle;
ekle=(NODE*)malloc(sizeof(NODE));
strcpy(ekle->word,word);
这里分配NODE
结构,但不为ekle->word
分配内存,因此它指向不确定的内存。你有两个地方的上述代码。
等于上述分配问题,你有
char *word;
strcpy(word,get_word(fp));
这里也没有为word
分配内存,所以你有一个指向不确定内存的指针。
另外,在C you should not cast the return of malloc
中。您还应该注意编译器发出的警告,如果您没有从代码中获取任何警告,则需要启用更多警告。编译器警告通常是undefined behavior的标志,这就是上述所有内容。最后,在编译器旁边,我认为调试器是开发人员最好的工具。学会使用它,它可以帮助你解决上述一些问题。
答案 1 :(得分:2)
这是一个问题:
char c;
do {
c = fgetc(fp);
if (c == EOF)
return 0;
这是错的; fgetc()
返回int
,因为EOF
不适合char
。因此第一行应该是:
int c;
答案 2 :(得分:0)
不是段错误,而是:你malloc str,不使用或释放它
void insert(NODE* sortedList, char *word) {
printf("INSERT ");
char *str = (char*)malloc(sizeof(char)*100);
答案 3 :(得分:0)
您必须验证文件是否正确打开。然后AFAIK strcpy要求目的地有足够的空间来存储数据(第74行),而不是&#34; char * word&#34;使用&#34;字符[255]&#34;例如(如果您知道大小限制)。
答案 4 :(得分:0)
您的主要问题在于:
*str++ = tolower(c);
首先,一旦增加str
,就不再拥有指向动态分配内存的指针。因此,您将无法在程序执行的稍后时间释放该内存,这最终会导致内存泄漏。其次,当你在函数末尾返回str
时,你不返回指向该字符串的指针,正如你可能希望的那样。
其他问题包括:
str
指向的字符串。str
,您不会取消分配EOF
指向的字符串。int
来存储函数fgetc
的返回值。以下是您的功能应如下所示:
#define MAX_WORD_LEN 101
char* get_word(FILE* fp)
{
char* str = (char*)malloc(sizeof(char)*MAX_WORD_LEN);
int c,i;
do
{
c = fgetc(fp);
if (c == EOF)
{
free(str);
return 0;
}
}
while (!isalpha((char)c));
i = 0;
do
{
str[i++] = tolower((char)c);
c = fgetc(fp);
}
while (isalpha((char)c) && i < MAX_WORD_LEN-1);
str[i] = 0;
return str;
}
请注意,如果文件中的单词长度超过MAX_WORD_LEN-1
个字符,那么您将基本上“丢失”最后读取的字符,因为它不会存储在任何位置。
答案 5 :(得分:0)
在这里,我编写的代码可以帮助您理解问题。它与您的程序的功能并不完全相同,但有些类似且更容易理解,并且还可以从以下代码中找到所有问题解决方案:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct NODE
{
char word[100];
int count;
struct NODE *next;
}NODE;
NODE *head = NULL;
NODE *list = NULL;
void insert(char *word)
{
if (list == NULL)
{
list = calloc(1, sizeof(NODE));
if (NULL == list)
{
perror("Memory allocation failed");
return;
}
strncpy(list->word, word, 99);
list->count = 1;
list->next = NULL;
head = list;
}
else
{
list->next = calloc(1, sizeof(NODE));
if (NULL == list->next)
{
perror("Memory allocation failed");
return;
}
strncpy(list->next->word, word, 99);
list->next->count = 1;
list->next->next = NULL;
list = list->next;
}
}
void createList(FILE* fp)
{
char word[100] = {0};
while (EOF != fscanf(fp, "%99s", word))
{
if (0 < strlen(word))
{
insert(word);
}
memset(word, 0x00, 100);
}
}
int main()
{
FILE *fp = NULL;
fp = fopen("text.txt", "r");
if (NULL == fp)
{
//File is not readable
perror("text.txt file open failed");
return -1;
}
createList(fp);
list = head;
while(NULL != list)
{
printf("%s\n", list->word);
list = list->next;
}
if (NULL != fp)
{
fclose(fp);fp = NULL;
}
return 0;
}
还创建函数来释放插入函数中分配的所有内存。