[英]Linked List C program results in segmentation fault:11
我有一个正在做作业的程序。 这必须是一个链表,该链表从文件中逐个字符地读取字符,然后创建单词,然后将其写入输出文件。 我能够只使用警告而没有错误地编译代码。 当我尝试使用input.txt
和output.txt
运行程序时,程序运行,然后终端生成第一行,该行被file opened
随后出现segmentation fault:11
我不知道如何解决此问题或解决该问题它固定。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct s_words {
char *str;
int count;
struct s_words* next;
}
words;
words *create_words(char *word) {
//allocate space for the structure
words *newWord = malloc(15);
if (NULL != newWord) {
//allocate space for storing the new word in "str"
//if str was array of fixed size, storage would be wasted
newWord->str = (char *)malloc(strlen(word));
strcpy(newWord->str, word); //copy word into newWord->str
newWord->str[strlen(word)] = '\0';
newWord->count = 1; //initialize count to 1;
newWord->next = NULL; //initialize next;
}
return newWord;
}
words *add_word(words *wordList, char *word) {
int found = 0;
words *temp = wordList;
// search if word exists in the list; if so, make found=1
while (temp != NULL) {
if (strcmp(temp, word)) { //use strcmp command
found = 1;
wordList->count++; //increment count;
return wordList;
} else {
temp = temp->next; //update temp
}
}
if (found == 0) { //new word
words *newWord = create_words(word);
if (NULL != newWord) {
wordList = newWord;
newWord->next = temp;
//?? Insert new word at the head of the list
}
return newWord;
}
}
int main(int argc, char *argv[]) {
words *mywords; //head of linked list containing words
mywords = NULL;
FILE *myFile;
myFile = fopen(argv[0], "r"); //first parameter is input file
if (myFile == 0) {
printf("file not opened\n");
return 1;
} else {
printf("file opened \n");
}
//start reading file character by character;
//when word has been detected; call the add_word function
int ch, word = 0, k = 0;
char thisword[100];
while ((ch = fgetc(myFile)) != EOF) {
if (ch == ' ') { //detect new word? Check if ch is a delimiter
if (word == 1) { //make sure previous character was not delimiter
printf("hi");
word = 0;
thisword[k] = '\0'; //make the kth character of thisword as \0
add_word(mywords, thisword); //now call add_word to add thisword into the list
mywords = NULL;
k = 0;
}
} else {
word = 1;
thisword[k] = ch; //make the kth character of thisword equal to ch
k++;
}
}
fclose(myFile);
words *currword;
printf("printing list\n");
words *temp;
//Traverse list and print each word and its count to outputfile
//output file is second parameter being passed
FILE *outputFile;
outputFile = fopen(argv[1], "w");
if (outputFile == 0) {
printf("file not opened\n");
return 1;
} else {
printf("file opened \n");
}
currword = mywords;
while (currword != NULL) {
fprintf(outputFile, "HI");
fprintf(outputFile, "%s %d" , currword, currword->count);
temp = currword;
currword = temp->next;
}
return 0;
}
任何帮助将不胜感激
编辑这是更新的代码: CODE
现在的新输出是:这是文件test.txt results.txt文件已打开,hihihihihihihihihihihihihihihiprinting列表文件未打开中止陷阱:6
在word
结构中分配字符串的方式不正确:
newWord->str = (char *)malloc(strlen(word));
strcpy(newWord->str, word); //copy word into newWord->str
newWord->str[strlen(word)]='\0';
您必须为'\\0'
终止符再分配一个字节:
newWord->str = malloc(strlen(word) + 1);
strcpy(newWord->str, word);
您可以通过一次调用strdup()
来简化此strdup()
:
newWord->str = strdup(word);
此外,您调用strcmp(temp, word)
将该单词与当前条目的字符串进行比较,这是不正确的,并且编译器必须针对此错误发出警告。 您应该改写:
if (strcmp(temp->str, word)) {
在main()
,您错误地调用了add_word()
:
add_word(mywords, thisword); //now call add_word to add thisword into the list
mywords = NULL;
您应该写:
mywords = add_word(mywords, thisword); //now call add_word to add thisword into the list
在打印循环中,将currword
传递给printf
的%s
而不是currword->str
。 您也不需要额外的temp
变量:
while (currword != NULL) {
fprintf(outputFile, "HI");
fprintf(outputFile, "%s %d" , currword->str, currword->count);
currword = currword->next;
}
编辑 :您的函数add_word
并不总是将值返回给调用者,并且它不能正确地将newWord插入列表的开头。
这是修改后的版本:
words *add_word(words *wordList, char *word) {
// search if word exists in the list; if update count and return
for (words *temp = wordList; temp != NULL; temp = temp->next) {
if (strcmp(temp, word)) { //use strcmp command
wordList->count++; //increment count;
return wordList;
}
}
words *newWord = create_words(word);
if (newWord != NULL) {
// Insert new word at the head of the list
newWord->next = wordList;
wordList = newWord;
}
return newWord;
}
最后,出现段错误的原因可能是,当您从输入文件中读取字符时,未在向其添加字符时检查数组大小。 您可能想知道为什么,由于输入文件中可能包含小的单词...但是您没有读取作为第一个命令行参数传递的输入文件,因此您正在读取可执行文件本身:
myFile = fopen(argv[0], "r"); //first parameter is input file
argv[0]
是执行程序的名称。
您还应该更改另一个fopen
,否则将覆盖input.txt
文件:
myFile = fopen(argv[1], "r"); //first parameter is input file
...
outputFile = fopen(argv[2], "w"); // second parameter is output file
学习调试自己很重要。 您应该利用一些调试工具。
使用-g标志编译程序,然后使用其中之一运行它以探究您的问题。 在修正警告时,也请听取评论者的建议。
GDB https://www.gnu.org/software/gdb/
瓦尔格朗德http://valgrind.org/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.