C 尝试在插入期间消除列表中的重复项
我正在编写一个C程序,它获取CSV格式的书籍数据作为输入(ISBN代码、标题、作者),并创建一个排序的链表。列表按作者排序,然后按标题排序。对于每本书,它需要跟踪输入的书的数量。为了实现这一点,我需要消除列表中的所有重复项,并且每次遇到重复项时,将book struct中的“totalCopies”计数器增加1。我可以创建一个函数,在注册所有输入后解析列表,但我觉得在用户接收输入时这样做更有效 兴趣函数报告如下,每次输入书籍内容时都会调用该函数:C 尝试在插入期间消除列表中的重复项,c,list,C,List,我正在编写一个C程序,它获取CSV格式的书籍数据作为输入(ISBN代码、标题、作者),并创建一个排序的链表。列表按作者排序,然后按标题排序。对于每本书,它需要跟踪输入的书的数量。为了实现这一点,我需要消除列表中的所有重复项,并且每次遇到重复项时,将book struct中的“totalCopies”计数器增加1。我可以创建一个函数,在注册所有输入后解析列表,但我觉得在用户接收输入时这样做更有效 兴趣函数报告如下,每次输入书籍内容时都会调用该函数: void insertBook(BookPtr
void insertBook(BookPtr *listPtr, const char *isbn, const char *title, const char *author) {
// new node
BookPtr newPtr = malloc(sizeof(Book));
if (newPtr != NULL) {
// initializing the new node
strcpy(newPtr->isbn, isbn);
strcpy(newPtr->title, title);
strcpy(newPtr->author, author);
newPtr->nextPtr = NULL;
BookPtr previousPtr = NULL;
BookPtr currentPtr = *listPtr;
while (currentPtr != NULL && strcmp(author, currentPtr->author) > 0) {
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if (previousPtr == NULL) { //empty list
newPtr->nextPtr = *listPtr;
*listPtr = newPtr;
} else {
while (currentPtr != NULL && strcmp(title, currentPtr->title) > 0 && !(strcmp(author, currentPtr->author))) {
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if(!(strcmp(previousPtr->isbn, newPtr->isbn))) { //this is the part that doesn't work. it should check if the new book and the one in the position where i would insert it have the same isbn code
currentPtr->totCopies = (currentPtr->totCopies) + 1;
} else {
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
}
}
}
else {
puts("Error");
}
}
这就是我试图将要插入的新书与列表中插入点之前的新书进行比较的方式
if(!(strcmp(previousPtr->isbn, newPtr->isbn)))
这似乎不起作用。previousPtr没有像我预期的那样指向前一个节点,而是指向其他元素,但我还没有弄清楚到底是什么让它指向它们。当程序在while循环中滚动列表时,我希望它指向插入新书位置之前的最后一个节点,但事实并非如此
下面你可以在我的程序中找到部分代码,足以重现这个问题
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct book {
char isbn[7];
char title[151];
char author[151];
int totCopies;
struct book *nextPtr;
};
typedef struct book Book;
typedef Book *BookPtr;
Book getBook() {
Book book;
char data[212];
fgets(data, sizeof(data), stdin);
char *field;
field = strtok(data, ",\n");
if(field != NULL) {
strcpy(book.isbn, field);
}
field = strtok(NULL, ",\n");
if(field != NULL) {
strcpy(book.title, field);
}
field = strtok(NULL, ",\n");
if(field != NULL) {
strcpy(book.author, field);
}
book.totCopies = 0;
return book;
}
void insertBook(BookPtr *listPtr, const char *isbn, const char *title, const char *author) {
// new node
BookPtr newPtr = malloc(sizeof(Book));
if (newPtr != NULL) {
// initializing the new node
strcpy(newPtr->isbn, isbn);
strcpy(newPtr->title, title);
strcpy(newPtr->author, author);
newPtr->nextPtr = NULL;
BookPtr previousPtr = NULL;
BookPtr currentPtr = *listPtr;
while (currentPtr != NULL && strcmp(author, currentPtr->author) > 0) {
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if (previousPtr == NULL) { //empty list
newPtr->nextPtr = *listPtr;
*listPtr = newPtr;
} else {
while (currentPtr != NULL && strcmp(title, currentPtr->title) > 0 && !(strcmp(author, currentPtr->author))) {
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if(!(strcmp(previousPtr->isbn, newPtr->isbn))) { //this is the part that doesn't work. it should check if the new book and the one in the position where i would insert it have the same isbn code
currentPtr->totCopies = (currentPtr->totCopies) + 1;
} else {
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
}
}
}
else {
puts("Error");
}
}
int main() {
Book l;
Book *listPtr = NULL;
l = getBook();
while(strcmp(l.isbn, "0")) {
insertBook(&listPtr, l.isbn, l.title, l.author);
l = getBook();
}
return 0;
}
#包括
#包括
#包括
结构书{
char-isbn[7];
字符标题[151];
char作者[151];
整版;
结构书*nextPtr;
};
typedef结构书;
typedef Book*BookPtr;
bookgetbook(){
书籍;
字符数据[212];
fgets(数据、尺寸(数据)、标准数据);
字符*字段;
字段=strtok(数据,“,\n”);
如果(字段!=NULL){
strcpy(book.isbn,field);
}
字段=strtok(空,“,\n”);
如果(字段!=NULL){
strcpy(书名、字段);
}
字段=strtok(空,“,\n”);
如果(字段!=NULL){
strcpy(book.author,field);
}
book.totCopies=0;
还书;
}
void insertBook(BookPtr*listPtr,const char*isbn,const char*title,const char*author){
//新节点
BookPtr newPtr=malloc(sizeof(Book));
如果(newPtr!=NULL){
//初始化新节点
strcpy(newPtr->isbn,isbn);
strcpy(新建PTR->标题,标题);
strcpy(newPtr->author,author);
newPtr->nextPtr=NULL;
BookPtr-previousPtr=NULL;
BookPtr currentPtr=*listPtr;
而(currentPtr!=NULL&&strcmp(author,currentPtr->author)>0){
先前的PTR=当前的PTR;
currentPtr=currentPtr->nextPtr;
}
if(previousPtr==NULL){//空列表
newPtr->nextPtr=*listPtr;
*listPtr=newPtr;
}否则{
而(currentPtr!=NULL&&strcmp(title,currentPtr->title)>0&&strcmp(author,currentPtr->author)){
先前的PTR=当前的PTR;
currentPtr=currentPtr->nextPtr;
}
如果(!(strcmp(previousPtr->isbn,newPtr->isbn)){//这是不起作用的部分。它应该检查新书和我要插入它的位置的书是否有相同的isbn代码
currentPtr->totCopies=(currentPtr->totCopies)+1;
}否则{
上一个PTR->下一个PTR=newPtr;
newPtr->nextPtr=currentPtr;
}
}
}
否则{
看跌期权(“错误”);
}
}
int main(){
l册;
Book*listPtr=NULL;
l=getBook();
而(strcmp(l.isbn,0){
insertBook(&listPtr,l.isbn,l.title,l.author);
l=getBook();
}
返回0;
}
有什么想法吗?请从和开始。特别是,您的问题只包含解释(“似乎不起作用”),而忽略了观察结果。此外,它不包含a,这是为了确保问题的质量而必须的。
typedef Book*BookPtr
的风格很差-不要将指针隐藏在typedef后面,因为这会让人困惑。在insertBook
中,我会在堆栈上初始化一本书
,遍历列表,如果不增加totCopies
,则只在堆上分配(并调用memcpy
)。Samuele,这仍然不完整,因为它缺少手动输入。此外,我想知道您是否可以剥离一些字段以进一步减少示例。最后,您仍然没有提供实际的观察结果,这可能也取决于您提供的输入,这更是删除手动输入的原因。哦,顺便说一句:查找教程,了解如何使用调试器逐步完成代码!你自己会很容易发现错误的。