在尝试打印句子时,获取空格或NULL节点时出现问题。
输入文件是txt文件,内容为"这是我们发光的时候了",没有引用
还存在两个空输出文件,用于以后与当前问题无关的输出。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 200
typedef struct data{
char *word;
struct data *next;
}node;
node *head=NULL;
node *copy=NULL;
node *prev=NULL;
int _log=-1;
void read_content(char *filename);//prototype
node* create_word(char *string);//prototype
void add_word(node *word);//prototype
void delete_word(char *string);//prototype
void print_words();//prototype
void log_it(node *curr, node *next, int op);//prototype
void undo();//prototype
int main(int argc, char *argv[]){
if(argc!=4){
printf("nInvalid parameters");
return 0;
}//end if
head=malloc(sizeof(node));
copy=malloc(sizeof(node));
prev=malloc(sizeof(node));
read_content(argv[1]);
int option=4;
int stringLength;
char *del_word=malloc(sizeof(char) * MAX);
char *word=malloc(sizeof(char) * MAX);
node *addit;
while(option!=0){
printf("nSentence: ");
print_words();
printf("nMenu: n(1) Add new wordn(2) Delete wordn(3) Undo last actionn(0) ExitnOption: ");
scanf("%d", &option);
if(option==1){//add new word
printf("nPlease enter new word: ");
scanf("%s", word);
addit=create_word(word);
printf("n%s", word);
add_word(addit);
}//end if
else if(option==2){//delete option
printf("nPlease enter word to delete: ");
scanf("%s", del_word);
delete_word(del_word);
}//end if
else if(option==3){
undo();
}//end if
else if(option==0){
printf("nTerminating program");
return 0;
}//end if
else{
printf("nUnrecognized option");
}//end else
}//end while
return 0;
}//end main
//this is course cs2050
void read_content(char *filename){
FILE *input=fopen(filename, "r");
if(input==NULL){
head=NULL;
printf("nEmpty list started");
}
char s[MAX];
char* token;
while(fgets(s, sizeof(s), input) != NULL)
{
int length = strlen(s)-1;
if(s[length] == 'n')
s[length] = ' ';
}//end while
token = strtok(s, " ");
//head = NULL;
node *newnode;
while (token)
{
char *s = malloc(sizeof(char) * strlen(token));
strcpy(s, token);
newnode=create_word(s);//create new node
printf("n%s", newnode->word);//error checking
add_word(newnode);//add to linked list
token = strtok(NULL, " ");
}//end while
fclose(input);
}//end read content
//creates node from char string
node* create_word(char *string){
node *newNode=malloc(sizeof(node));
newNode->word=string;
newNode->next=NULL;
return newNode;
}//end create word
//adds node to link list
void add_word(node *word){
node *current=head;
if(current==NULL){
current=word;
}//end if
else{
while(current->next!=NULL){
current=current->next;
}//end while;
current->next=word;
}//end else
//printf("n%s", current->next->word);
_log=1;
}//end add word
void delete_word(char *string){
node *current=head;
node *previous=NULL;
while(string!=current->word){
previous=current;
current=current->next;
}//end while
if(string==current->word){
previous->next=current->next;
copy->word=current->word;
copy->next=current->next;
prev=current;
}//end while
_log=-1;
}//end delete word
//function to print linked list as sentence
void print_words(){
node *printhead=head;
//printf("n");
//printhead=printhead->next;
while(printhead!=NULL){
printf("%s ", printhead->word);
printhead=printhead->next;
}//end while
}//end print words
void log_it(node *curr, node *next, int op){
}//end log it
void undo(){
node *current=head;
node *prev=malloc(sizeof(node));
if(_log==-1)//last action was delete word
{
}//end if
else if(_log==1)//last action was insert word
{
}//end else if
else{
}//end else
}//end undo
以下输出:
print_words()打印以下内容:(空)这是我们闪耀的时刻
一开始似乎有一个空节点在发挥作用,但似乎找不到原因。
这是工作代码;它比您提供的更接近SSCCE。由于处理空列表的方式,出现了空指针(打印为(null)
)的问题。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 200
typedef struct data
{
char *word;
struct data *next;
} node;
node *head = NULL;
static void read_content(char *filename);
static node *create_word(char *string);
static void add_word(node *word);
static void print_words(void);
int main(int argc, char *argv[])
{
if (argc!=2)
{
fprintf(stderr, "Usage: %s filen", argv[0]);
return 1;
}
read_content(argv[1]);
print_words();
return 0;
}
void read_content(char *filename)
{
FILE *input = fopen(filename, "r");
if (input==NULL)
{
fprintf(stderr, "Failed to open file %s for readingn", filename);
exit(1);
}
char s[MAX];
while (fgets(s, sizeof(s), input) != NULL)
{
int length = strlen(s)-1;
if (s[length] == 'n')
s[length] = ' ';
char* token = strtok(s, " ");
while (token)
{
char *s = malloc(sizeof(char) * (strlen(token) + 1));
strcpy(s, token);
node *newnode = create_word(s);
printf("Word: %sn", newnode->word);
add_word(newnode);
token = strtok(NULL, " ");
}
}
fclose(input);
}
node *create_word(char *string)
{
node *newNode = malloc(sizeof(node));
newNode->word = string;
newNode->next = NULL;
return newNode;
}
void add_word(node *word)
{
if (head == NULL)
head = word;
else
{
node *current = head;
while (current->next != NULL)
current=current->next;
current->next = word;
}
}
void print_words(void)
{
for (node *pw = head; pw != NULL; pw = pw->next)
printf("%s ", pw->word);
putchar('n');
}
read_content()
的结构已被修改,因此它读取文件中所有行中的所有单词,而不仅仅是文件的最后一行。main()
中head
的内存分配导致输出中出现伪(null)
。add_word()
中的代码也是固定的。函数print_words()
已被重写。大部分多余的材料都被无情地清除了;剩下的东西或多或少是证明问题已经解决的必要条件。仍有改进的余地。read_content()
中的字符串分配和复制可能在create_word()
中处理得更好;您可能不想也可能不想考虑使用strdup()
来复制字符串。