Προς το περιεχόμενο

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • 0
feugatos

Λίγη βοήθεια για τις συνδεδεμένες λίστες στη C

Ερώτηση

Γειά σας παιδία,

Προσπαθώ να φτιάξω ένα πρόγραμμα το οποίο θα χρησιμοποιεί μονά ή διπλά

συνδεδεμένη λίστα από structs και το οποίο θα χρησιμεύει στη διαχείρηση της συλλογής

βιβλίων που έχει κάποιος.

Αυτό που θέλω να πετύχω είναι αφού δημιουργηθεί η λίστα, τα δεδομένα να

αποθηκεύονται σε ένα αρχείο και κάθε σειρά να αντιστοιχεί σε ένα μόνο node της

λίστας. (Αυτό ξέρω ότι θα γίνει με την fprintf)

Κάτι άλλο που θέλω να κάνω είναι όταν έχω ένα τέτοιο αρχείο να μπορώ να παίρνω την

κάθε σειρά μια μια και απο αυτή να δημιουργώ τη λίστα.

Μπορεί κανείς να με βοηθήσει με το τελευταίο;

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

8 απαντήσεις σε αυτή την ερώτηση

Προτεινόμενες αναρτήσεις

bokarinho επειδή μπερδεύτηκα λιγάκι, μπορείς να μου γράψεις τον κώδικα ο οποίος αν έχω ένα αρχείο

με τα εξής δεδομένα

 

2257, Onoma, Syggrafeas, 2001

324, kostas, Giannis, 2002

34325, Ilias, Apostoloy, 2000

12345,Antwnis, Dimitrioy, 1999

112, Takis, Oreilly, 2007

 

θα μου τα φορτώσει σε μια λίστα από structs του τύπου

 

struct book

{

int id;

char book_name[50];

char book_writer[50];

int year_publiced;

int times_read;

struct book *next;

struct book *prev;

}

 

 

?

 

Ευχαριστώ...

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Ολοκληρωμένη μορφή όπως ακριβώς το θέλεις, δεν καταλαβαίνω δεν το βλέπεις; Ο κώδικας που σου έχω δώσει αυτό κάνει, τι ακριβώς δεν καταλαβαίνεις; Ο κώδικας έχει ως δουλειά να ανοίξει ένα αρχείο που περιέχει τις εγγραφές και να τις περάσει στην λίστα μας, και αυτό κάνει γιατί δεν το βλέπεις.

 

>
//---------------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFSZ 256
#define TOKENS 5

/* Seperator. */

const char *seperator = ",";


typedef struct _Book
{
int BookId;
char BookName[51];
char BookWriter[51];
int YearPublished;
int Times_Read;
/* Pointer to next and previous node. */
struct _Book *next;
struct _Book *previous;
}Book;

typedef struct _BookList
{
Book *head;
Book *tail;
int BookListSz;
}BookList;
#pragma hdrstop

//---------------------------------------------------------------------------

/* Functions. */

/* Error Reporter. */
void _perror(const char *Msg)
{
printf("Error: %s\n", Msg);
}

/* Create A Book Node. */
Book *CreateBook(int BkId, char *BkName, char *BkWriter, int YrPub, int TimesRead)
{
Book *b = NULL;
if((b = malloc(sizeof(Book))) == NULL)
{
	_perror("Book Creation.");
	return NULL;
}
else
{
	/* Init. */
	b->BookId = BkId;
	b->Times_Read = TimesRead;
	strcpy(b->BookName, BkName);
	strcpy(b->BookWriter, BkWriter);
	b->YearPublished = YrPub;
	/* NULL. */
	b->next = NULL;
	b->previous = NULL;
	/* Return. */
	return b;
}
}

/* Create A Book List. */
BookList *CreateBookList(const int nrLists)
{
/* List. */
BookList *bl = NULL;
if((bl = calloc(nrLists, sizeof(BookList))) == NULL)
{
	_perror("List Creation.");
	return NULL;
}
else
{
	/* Init. */
	bl->head = NULL;
	bl->tail = NULL;
	bl->BookListSz = 0;

	/* Return the list. */
	return bl;
}
}

int insertBookIntoBookList(BookList *List, Book *element, int BkId, char *BkName, char *BkWriter, int YrPub, int TimesRead)
{
/* Our Book to Add. */
Book *nPtrBook = NULL;

if(element == NULL && List->BookListSz != 0)
{
	_perror("Invalid Insertion.");
	return -1;
}
/* Create the Book. */
nPtrBook = CreateBook(BkId, BkName, BkWriter, YrPub, TimesRead);

/* Case Empty List. */
if(!List->BookListSz)
{
	List->head = nPtrBook;
	List->head->next = NULL;
	List->head->previous = NULL;
	List->tail = nPtrBook;
}
else
{
	nPtrBook->next = element->next;
	nPtrBook->previous = element;
	if(element->next == NULL)
		List->tail = nPtrBook;
	else
		element->next->previous = nPtrBook;
	element->next = nPtrBook;
}
/* Advance Size. */
List->BookListSz++;
/* Return. */
return 0;
}
/* Get a Line From Input File and seperate it. */
int GetLineFromFile(const char *filename, int *Cnt, Book **ptrLine)
{
if(!filename)
{
	_perror("Invalid File Name.");
	return -1;
}
else
{
	FILE *fileptr = NULL;
	if((fileptr = fopen(filename, "rt")) == NULL)
	{
		_perror("Open File.");
		return -2;
	}
	else
	{
		/* Basic Variables. */
		char *tokenPtr = NULL;
		char *TBuffer = NULL;
		Book *Lineptr = NULL;
		/* Case Status. */
		int nCase = 0, jDx = 0;
		/* Error Checking. */
		static int nError = 0;
		/* Get Memory. */
		if((TBuffer = calloc(BUFSZ, sizeof(char))) == NULL)
		{
			_perror("Memory Fault.");
			/* Close File. */
			fclose(fileptr);
			return -3;
		}
		if((Lineptr = malloc(sizeof(Book))) == NULL)
		{
			_perror("Memory Fault.");
			/* Free memory. */
			free(TBuffer);
			fclose(fileptr);
			return -4;
		}
		else
		{
			while(fgets(TBuffer, BUFSZ, fileptr) != NULL)
			{
				if(TBuffer[strlen(TBuffer)-1] == '\n')
					TBuffer[strlen(TBuffer)-1] = '\0';

				tokenPtr = strtok(TBuffer,seperator);
				if(!tokenPtr)
				{
					nError = 1;
					_perror("Invalid Text Line Type.");
					break;
				}
				else
				{
					while(tokenPtr && nCase < TOKENS)
					{
						switch(nCase)
						{
							case 0:
								sscanf(tokenPtr, "%d", &Lineptr[jDx].BookId);
								break;
							case 1:
								strcpy(Lineptr[jDx].BookName,tokenPtr);
								break;
							case 2:
								strcpy(Lineptr[jDx].BookWriter,tokenPtr);
								break;
							case 3:
								sscanf(tokenPtr, "%d", &Lineptr[jDx].YearPublished);
								break;
							case 4:
								sscanf(tokenPtr, "%d", &Lineptr[jDx].Times_Read);
								break;
						default:
						   break;
						}
						tokenPtr = strtok(NULL, seperator);
						/* Advance Case Status. */
						nCase++;
					}
				}
				/* Advance jDx. */
				jDx++;
				/* Zero nCase. */
				nCase = 0;
				/* Clear TBuffer. */
				memset(TBuffer, 0 , strlen(TBuffer));
				/* Realloc Line. */
				Lineptr = realloc(Lineptr, (jDx+1) * sizeof(Book));
			}
			if(nError)
			{
				free(TBuffer);
				free(Lineptr);
				fclose(fileptr);
				return -4;
			}
			/* EXIT SUCCESS. */
			else
			{
				/* Return Values. */
				*ptrLine = Lineptr;
				*Cnt = jDx;
				free(TBuffer);
				fclose(fileptr);
				return 0;
			}
		}
	}
}
}
/* Dump A Book List. */
void DumpBookList(const BookList *List)
{
/* Pointer to BookList. */
Book *ptrBook = NULL;
/* Print Action. */
printf("Book List:\n");
for(ptrBook = List->head; ptrBook != NULL; ptrBook = ptrBook->next)
	printf("%d,%s,%s,%d,%d\n", ptrBook->BookId, ptrBook->BookName, ptrBook->BookWriter, ptrBook->YearPublished, ptrBook->Times_Read);

}

#pragma argsused
int main(int argc, char* argv[])
{
int i,Cnt = 0;
Book *nrBooks = NULL;
BookList *List = CreateBookList(1);

GetLineFromFile("file.txt", &Cnt, &nrBooks);

for(i = 0; i < Cnt; i++)
{
	insertBookIntoBookList(List, List->tail,nrBooks[i].BookId, nrBooks[i].BookName, nrBooks[i].BookWriter, nrBooks[i].YearPublished, nrBooks[i].Times_Read);
}
/* Dump Book List. */
   DumpBookList(List);

printf("Hit enter to continue....");
getchar();
return 0;
}
//---------------------------------------------------------------------------

 

Παράδειγμα Αρχείου:

 

2257, Onoma, Syggrafeas, 2001,500

324, kostas, Giannis, 2002,200

34325, Ilias, Apostoloy, 2000,12

12345,Antwnis, Dimitrioy, 1999,23

112, Takis, Oreilly, 2007,34

 

Εκτυπωμένα αποτελέσματα:

 

Book List:

2257, Onoma, Syggrafeas,2001,500

324, kostas, Giannis,2002,200

34325, Ilias, Apostoloy,2000,12

12345,Antwnis, Dimitrioy,1999,23

112, Takis, Oreilly,2007,34

Hit enter to continue....

 

*Βέβαια κακό σου κάνω γιατί σου τα δίνω στο πιάτο αλλά τουλάχιστον ελπίζω να καταλάβεις πως δουλεύει το όλο concept.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
Γειά σας παιδία,

Προσπαθώ να φτιάξω ένα πρόγραμμα το οποίο θα χρησιμοποιεί μονά ή διπλά

συνδεδεμένη λίστα από structs και το οποίο θα χρησιμεύει στη διαχείρηση της συλλογής

βιβλίων που έχει κάποιος.

Αυτό που θέλω να πετύχω είναι αφού δημιουργηθεί η λίστα, τα δεδομένα να

αποθηκεύονται σε ένα αρχείο και κάθε σειρά να αντιστοιχεί σε ένα μόνο node της

λίστας. (Αυτό ξέρω ότι θα γίνει με την fprintf)

Κάτι άλλο που θέλω να κάνω είναι όταν έχω ένα τέτοιο αρχείο να μπορώ να παίρνω την

κάθε σειρά μια μια και απο αυτή να δημιουργώ τη λίστα.

Μπορεί κανείς να με βοηθήσει με το τελευταίο;

 

Όλα αυτά που λες είναι εφικτά, ποια θες να είναι η μορφή του κόμβου της λίστας; Δηλαδή τι αποθηκεύεις μέσα στο struct; Έχεις κάνει κάποιο κώδικα; Θέλεις μονά ή διπλά συνδεδεμένη λίστα; Και με μονά μπορείς να κάνεις δουλειά σίγουρα.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Το struct είναι το εξής:

 

struct book

{

int id;

char book_name[50];

char book_writer[50];

int year_publiced;

int times_read;

struct book *next;

struct book *prev;

}

 

Ενώ η fprintf έχει την εξής μορφή:

 

fprintf(pf, "%d, %s, %s, %d, %d\n", new_book->id, new_book->book_name, new_book->bood_writer, new_book->year_publiced, new-book->times_read);

 

Οπότε κάθε σειρά του αρχείου θα είναι κάπως έτσι:

 

2257, Onoma, Syggrafeas, 2001, 5

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
Το struct είναι το εξής:

 

struct book

{

int id;

char book_name[50];

char book_writer[50];

int year_publiced;

int times_read;

struct book *next;

struct book *prev;

}

 

Ενώ η fprintf έχει την εξής μορφή:

 

fprintf(pf, "%d, %s, %s, %d, %d\n", new_book->id, new_book->book_name, new_book->bood_writer, new_book->year_publiced, new-book->times_read);

 

Οπότε κάθε σειρά του αρχείου θα είναι κάπως έτσι:

 

2257, Onoma, Syggrafeas, 2001, 5

 

To παρακάτω πρόγραμμα το οποίο δεν είναι πληρως ολοκληρωμένο μιας και έχω ξεχάσει να προσθέσω ένα μέλος στην δομή το οποίο το είδα τώρα :rolleyes: κάνει αυτό που θέλεις δηλαδή διαβάζει από ένα αρχείο κειμένου πχ: file.txt τα περιεχόμενα και τα πετάει σε μία διπλά συνδεδεμένη λίστα όπως την έχουμε ορίσει. Δεν έχω κάνει ακόμα την συνάρτηση που να γράφει σε αρχείο, πειραματίσου όμως γιατί από ότι είδα το κόλπο το ξέρεις. Αν έχω χρόνο θα την διορθώσω...

 

>
//---------------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFSZ 256
#define TOKENS 4

/* Seperator. */

const char *seperator = ",";


typedef struct _Book
{
int BookId;
char BookName[51];
char BookWriter[51];
int YearPublished;
/* Pointer to next and previous node. */
struct _Book *next;
struct _Book *previous;
}Book;

typedef struct _BookList
{
Book *head;
Book *tail;
int BookListSz;
}BookList;
#pragma hdrstop

//---------------------------------------------------------------------------

/* Functions. */

/* Error Reporter. */
void _perror(const char *Msg)
{
printf("Error: %s\n", Msg);
}

/* Create A Book Node. */
Book *CreateBook(int BkId, char *BkName, char *BkWriter, int YrPub)
{
Book *b = NULL;
if((b = malloc(sizeof(Book))) == NULL)
{
	_perror("Book Creation.");
	return NULL;
}
else
{
	/* Init. */
	b->BookId = BkId;
	strcpy(b->BookName, BkName);
	strcpy(b->BookWriter, BkWriter);
	b->YearPublished = YrPub;
	/* NULL. */
	b->next = NULL;
	b->previous = NULL;
	/* Return. */
	return b;
}
}

/* Create A Book List. */
BookList *CreateBookList(const int nrLists)
{
/* List. */
BookList *bl = NULL;
if((bl = calloc(nrLists, sizeof(BookList))) == NULL)
{
	_perror("List Creation.");
	return NULL;
}
else
{
	/* Init. */
	bl->head = NULL;
	bl->tail = NULL;
	bl->BookListSz = 0;

	/* Return the list. */
	return bl;
}
}

int insertBookIntoBookList(BookList *List, Book *element, int BkId, char *BkName, char *BkWriter, int YrPub)
{
/* Our Book to Add. */
Book *nPtrBook = NULL;

if(element == NULL && List->BookListSz != 0)
{
	_perror("Invalid Insertion.");
	return -1;
}
/* Create the Book. */
nPtrBook = CreateBook(BkId, BkName, BkWriter, YrPub);

/* Case Empty List. */
if(!List->BookListSz)
{
	List->head = nPtrBook;
	List->head->next = NULL;
	List->head->previous = NULL;
	List->tail = nPtrBook;
}
else
{
	nPtrBook->next = element->next;
	nPtrBook->previous = element;
	if(element->next == NULL)
		List->tail = nPtrBook;
	else
		element->next->previous = nPtrBook;
	element->next = nPtrBook;
}
/* Advance Size. */
List->BookListSz++;
/* Return. */
return 0;
}
/* Get a Line From Input File and seperate it. */
int GetLineFromFile(const char *filename, int *Cnt, Book **ptrLine)
{
if(!filename)
{
	_perror("Invalid File Name.");
	return -1;
}
else
{
	FILE *fileptr = NULL;
	if((fileptr = fopen(filename, "rt")) == NULL)
	{
		_perror("Open File.");
		return -2;
	}
	else
	{
		/* Basic Variables. */
		char *tokenPtr = NULL;
		char *TBuffer = NULL;
		Book *Lineptr = NULL;
		/* Case Status. */
		int nCase = 0, jDx = 0;
		/* Error Checking. */
		static int nError = 0;
		/* Get Memory. */
		if((TBuffer = calloc(BUFSZ, sizeof(char))) == NULL)
		{
			_perror("Memory Fault.");
			/* Close File. */
			fclose(fileptr);
			return -3;
		}
		if((Lineptr = malloc(sizeof(Book))) == NULL)
		{
			_perror("Memory Fault.");
			/* Free memory. */
			free(TBuffer);
			fclose(fileptr);
			return -4;
		}
		else
		{
			while(fgets(TBuffer, BUFSZ, fileptr) != NULL)
			{
				if(TBuffer[strlen(TBuffer)-1] == '\n')
					TBuffer[strlen(TBuffer)-1] = '\0';

				tokenPtr = strtok(TBuffer,seperator);
				if(!tokenPtr)
				{
					nError = 1;
					_perror("Invalid Text Line Type.");
					break;
				}
				else
				{
					while(tokenPtr && nCase < TOKENS)
					{
						switch(nCase)
						{
							case 0:
								sscanf(tokenPtr, "%d", &Lineptr[jDx].BookId);
								break;
							case 1:
								strcpy(Lineptr[jDx].BookName,tokenPtr);
								break;
							case 2:
								strcpy(Lineptr[jDx].BookWriter,tokenPtr);
								break;
							case 3:
								sscanf(tokenPtr, "%d", &Lineptr[jDx].YearPublished);
								break;
						default:
						   break;
						}
						tokenPtr = strtok(NULL, seperator);
						/* Advance Case Status. */
						nCase++;
					}
				}
				/* Advance jDx. */
				jDx++;
				/* Zero nCase. */
				nCase = 0;
				/* Clear TBuffer. */
				memset(TBuffer, 0 , strlen(TBuffer));
				/* Realloc Line. */
				Lineptr = realloc(Lineptr, (jDx+1) * sizeof(Book));
			}
			if(nError)
			{
				free(TBuffer);
				free(Lineptr);
				fclose(fileptr);
				return -4;
			}
			/* EXIT SUCCESS. */
			else
			{
				/* Return Values. */
				*ptrLine = Lineptr;
				*Cnt = jDx;
				free(TBuffer);
				fclose(fileptr);
				return 0;
			}
		}
	}
}
}

#pragma argsused
int main(int argc, char* argv[])
{
int i,Cnt = 0;
Book *nrBooks = NULL;
Book *ptrBook = NULL;
BookList *List = CreateBookList(1);

GetLineFromFile("file.txt", &Cnt, &nrBooks);

for(i = 0; i < Cnt; i++)
{
	insertBookIntoBookList(List, List->tail,nrBooks[i].BookId, nrBooks[i].BookName, nrBooks[i].BookWriter, nrBooks[i].YearPublished);
}
/* Dump Book List. */
printf("Book List:\n");
for(ptrBook = List->head; ptrBook != NULL; ptrBook = ptrBook->next)
	printf("%d,%s,%s,%d\n", ptrBook->BookId, ptrBook->BookName, ptrBook->BookWriter, ptrBook->YearPublished);


printf("Hit enter to continue....");
getchar();
return 0;
}
//---------------------------------------------------------------------------

 

Παράδειγμα αρχείου:

 

2257, Onoma, Syggrafeas, 2001

324, kostas, Giannis, 2002

34325, Ilias, Apostoloy, 2000

12345,Antwnis, Dimitrioy, 1999

112, Takis, Oreilly, 2007

 

Εκτυπωμένα αποτελέσματα:

 

Book List:

2257, Onoma, Syggrafeas,2001

324, kostas, Giannis,2002

34325, Ilias, Apostoloy,2000

12345,Antwnis, Dimitrioy,1999

112, Takis, Oreilly,2007

Hit enter to continue....

 

Bokarinho!

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Βασικά μπρερδεύτηκα λιγάκι με τον κώδικα που μου έδωσες γιατί είμαι από τη μια αρχάριος και από

την άλλη δεν άφησες και κανένα σχόλιο ώστε να ξέρω τι κάνει τι.

Αν μπορείς απομόνωσέ μου μόνο τη συνάρτηση που διαβάζει το αρχείο σειρά σειρά και πες μου πως

λειτουργεί.

Μην με παρεξηγείς.

Ευχαριστώ για τον κόπο σου.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
×
×
  • Δημιουργία νέου...