Adding struct pointer to a pointer array - c

I have a problem and I really dont know what to do.
I'am trying to insert "new students" to an student-array. The array contains pointers to the created structs. Can somebody find the error? It adds the student-structs to the array but especially the printing doesnt work.
It would be really helpful, if somebody could help me. :) PS: You can just copy the code.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_HASH 10
typedef struct student
{
unsigned int matnr;
char *name;
struct student *next_student;
} Student;
Student **hash_tabelle[MAX_HASH];
void insert_student (unsigned int matnr, char *name)
{
Student *neuer_student = malloc(sizeof(Student));
neuer_student->name = malloc(sizeof(*name)+1);
neuer_student->matnr = matnr;
strcpy(neuer_student->name, name);
neuer_student->next_student = NULL;
// Index im Hash-Array ermitteln
int hash_index = matnr % 10;
if(hash_tabelle[hash_index] == NULL)
{
neuer_student->next_student = hash_tabelle[hash_index];
hash_tabelle[hash_index] = neuer_student;
}
else
{
while(*hash_tabelle[hash_index] != NULL && (((*hash_tabelle[hash_index])->matnr - neuer_student->matnr) <= 0))
hash_tabelle[hash_index] = &(*hash_tabelle[hash_index])->next_student;
neuer_student->next_student = *hash_tabelle[hash_index];
*hash_tabelle[hash_index] = neuer_student;
}
}
void print_hash_tabelle()
{
for(int i = 0; i != MAX_HASH - 1; i++){
printf("%d)\t", i);
hash_tabelle[i] = &(*hash_tabelle[i])->next_student;
for(; hash_tabelle[i] != NULL; hash_tabelle[i] = &(*hash_tabelle[i])->next_student){
printf("%s (%d)", (&(*hash_tabelle[i])->name), (&(*hash_tabelle[i])->matnr));
}
printf("\t");
}
}
int main()
{
unsigned int matnr;
char name[100];
do
{
printf("Matrikelnummer:\t");
scanf("%d", &matnr);
fflush(stdin);
getchar(); // um das \n aus dem Puffer zu kriegen und rauszuschmeißen
printf("Name:\t\t");
fgets(name, 30, stdin);
insert_student(matnr, name);
}
while (matnr != 0);
print_hash_tabelle();
return 0;
}

Using a hash table is so simple... No need to use dereferencing for a fixed-size array of linked-list pointers.
Step 1 - a hash table is a array of linked-list pointers.
As #BLUEPIXY suggests:
Student *hash_tabelle[MAX_HASH];
Step 2 - to allocate and free each linked-list, initialize each item to NULL.
Otherwise, if(hash_tabelle[hash_index] == NULL) is Undefined
behavior in the function insert_student().
void hash_init()
{
for(int i=0;i<MAX_HASH;i++) {
hash_tabelle[MAX_HASH]=NULL;
}
}
Step 3 - allocate enough char to store the char *name to insert_student().
As # WhozCraig suggests, use strlen().
void insert_student (unsigned int matnr, char *name)
{
Student *neuer_student = malloc(sizeof(Student));
neuer_student->name = malloc(strlen(name)+1);
neuer_student->matnr = matnr;
strcpy(neuer_student->name, name);
neuer_student->next_student = NULL;
Step 4 - add the neuer_student in the hash_tabelle[] (function insert_student())
Warning: the index shall be included in the size of the array
[0..MAX_HASH[. (using 10 instead of MAX_HASH could become a bug).
int hash_index = matnr % MAX_HASH;
When the hash_tabelle[hash_index] is NULL, simple store the
neuer_student. No need to modify neuer_student->next_student.
if(hash_tabelle[hash_index] == NULL)
{
hash_tabelle[hash_index] = neuer_student;
}
Else explore the linked-list of hash_tabelle[hash_index] to store
the neuer_student at the end.
else
{
Student *tmp;
tmp = hash_tabelle[hash_index];
while (tmp->next_student!=NULL) {
tmp = tmp->next_student;
}
tmp->next_student = neuer_student;
}
Step 5 - to print the all items of the hash table (function print_hash_tabelle())
Reuse the same method to explore each linked-list pointer.
Warning: explore all item from 0 to MAX_HASH-1
void print_hash_tabelle()
{
for(int i = 0; i < MAX_HASH; i++){ // ERR != MAX_HASH - 1; i++){
printf("%d)\t", i);
Student *tmp = hash_tabelle[i];
while (tmp!=NULL) {
printf("%s (%d)", tmp->name, tmp->matnr);
tmp = tmp->next_student;
}
printf("\n");
}
}
Step 6 - free the memory of each item of the hash_tabelle[].
Free the allocated string free(tmp->name);.
Remove the current student hash_tabelle[i] = tmp->next_student;
Free the allocated student free(tmp);
Repeat until the end of the linked-list
That's all (no change in the main() except adding a call to hash_free() at the end).
void hash_free()
{
for(int i=0;i<MAX_HASH;i++) {
Student *tmp = hash_tabelle[i];
while (tmp!=NULL) {
free(tmp->name);
hash_tabelle[i] = tmp->next_student;
free(tmp);
tmp = hash_tabelle[i];
}
}
}

like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_HASH 10
typedef struct student {
unsigned int matnr;
char *name;
struct student *next_student;
} Student;
Student *hash_tabelle[MAX_HASH];
void insert_student (unsigned int matnr, char *name){
Student *neuer_student = malloc(sizeof(Student));
neuer_student->name = malloc(strlen(name)+1);
strcpy(neuer_student->name, name);
neuer_student->matnr = matnr;
//neuer_student->next_student = NULL;
int hash_index = matnr % MAX_HASH;
Student head = { .next_student = hash_tabelle[hash_index] };
Student *prev = &head, *curr = head.next_student;
while(curr != NULL && curr->matnr <= neuer_student->matnr){
prev = curr;
curr = curr->next_student;
}
neuer_student->next_student = curr;
prev->next_student = neuer_student;
hash_tabelle[hash_index] = head.next_student;
}
void print_hash_tabelle(void){
for(int i = 0; i < MAX_HASH; i++){
printf("%d)\t", i);
for(Student *p = hash_tabelle[i]; p; p = p->next_student){
printf("%s (%d)\t", p->name, p->matnr);
}
printf("\n");
}
}
void free_hash_tabelle(void){
for(int i = 0; i < MAX_HASH; i++){
Student *p = hash_tabelle[i];
while(p){
Student *temp = p->next_student;
free(p->name);
free(p);
p = temp;
}
}
}
int main(void){
int matnr = -1;//for %d of scanf
char name[100];
while(1){
printf("Matrikelnummer(-1 for end input): ");fflush(stdout);
scanf("%d", &matnr);
if(matnr < 0)
break;
while(getchar() != '\n');
printf("Name: ");fflush(stdout);
fgets(name, sizeof name, stdin);
name[strcspn(name, "\n")] = 0;
insert_student(matnr, name);
}
print_hash_tabelle();
free_hash_tabelle();
return 0;
}

Related

Linked list being overwritten instead of attached to another linked list

This is written in C.
I'm trying to take user input and use it to create/add to a linked list, which I point to with struct Node *dict; Everything is accomplished using global memory.
Creating a new linked list works fine, but when the user tries to add to the linked list, it overwrites the extant linked list.
Here's my code for adding to the list (words is an array of nodes to be appended to the list):
if (dict == NULL) { // If previous list does not exist, global dict pointer should point to node array
dict = words;
} else { // Else find end of current linked list and point it to the new list
struct Node *head = dict;
while (head->next != NULL) {
head = head->next;
}
head->next = words;
}
When I create a list with the words "apple orange peach," for example, when I print the list, I get the output "apple orange peach." But then when I add "pear" to the list, "apple orange peach" is overwritten and I only see the output "pear," instead of "apple orange peach pear."
EDIT:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
//// GUI Stuff ////
void drawDashedLine() {
for (int i = 0; i < 30; i++) {
printf("-");
}
printf("\n");
}
void drawDottedLine() {
for (int i = 0; i < 30; i++) {
printf(".");
}
printf("\n");
}
void drawArrowLine() {
for (int i = 0; i < 30; i++) {
printf(">");
}
printf("\n");
}
void drawStarLine() {
for (int i = 0; i < 30; i++) {
printf("*");
}
printf("\n");
}
struct Node {
int length;
char word[5];
struct Node * next;
};
// Pointer to global linked list dictionary
struct Node *dict;
struct Node *newDict;
void printDict() {
drawDottedLine();
struct Node * head = dict;
while (head != NULL) {
printf("%s\n", head -> word);
head = head -> next;
}
drawDottedLine();
return;
}
void alphabetizeDict() { // Bubble sort
//printf("%p --- %p\n", dict, dict->next);
struct Node * head = dict;
if (head == NULL) {
return;
}
struct Node * ptr2 = NULL;
int swapped = 1;
while (swapped) {
swapped = 0;
head = dict;
while (head -> next != ptr2) {
char * temp1 = strdup(head -> word);
char * temp2 = strdup(head -> next -> word);
strupr(temp1);
strupr(temp2);
if (strcmp(temp1, temp2) > 0) {
char temp[5];
strcpy(temp, head -> word);
strcpy(head -> word, head -> next -> word);
strcpy(head -> next -> word, temp);
swapped = 1;
}
head = head -> next;
}
ptr2 = head;
}
return;
}
void createDict() {
// To hold the string entered by the user
char str[5000];
// Holds 1000 words, each up to 5 characters long (4 plus a NULL char)
char newString[1000][5];
printf("\n");
drawArrowLine();
printf("Enter word(s): \n");
fgets(str, sizeof str, stdin);
int i, j, ctr;
j = 0;
ctr = 0; // ctr to iterate through words, j to iterate through letters
for (i = 0; i <= (strlen(str)); i++) {
if (str[i] == ' ' || str[i] == '\0') { // This is whitespace. add null character to terminate string. Start next word
newString[ctr][j] = '\0';
ctr++;
j = 0;
} else { // Else add letter to string
newString[ctr][j] = str[i];
j++;
}
}
for (int i = 0; i < ctr; i++) {
struct Node n;
n.length = strlen(newString[i]);
int c = 0;
char sub[5];
// Only use word's first four letters
while (c < strlen(newString[i]) && c < 4) {
sub[c] = newString[i][c];
c++;
}
sub[c] = '\0';
strcpy(n.word, sub);
n.next = NULL;
if (dict == NULL) {
dict = &n;
} else {
n.next = dict;
dict = &n;
}
}
// alphabetizeDict();
printf("Word(s) added succesfully\n");
drawArrowLine();
printf("\n");
return;
}
void destroyDict() {
printf("Starting new dictionary......\n");
while (dict != NULL) {
struct Node * temp = dict;
dict = dict -> next;
temp -> next = NULL;
}
}
void caseInsensSearch(char * searchTerm) {
for (int i = 0; searchTerm[i]; i++) {
searchTerm[i] = tolower(searchTerm[i]);
}
struct Node * head = dict;
int index = 0;
while (head != NULL) {
char lowercaseWord[5];
for (int i = 0; head -> word[i]; i++) {
lowercaseWord[i] = tolower(head -> word[i]);
}
if (strcmp(lowercaseWord, searchTerm) == 0) {
printf("Found %s at index %i\n", head -> word, index);
drawDashedLine();
return;
}
head = head -> next;
index++;
}
printf("Sorry, I couldn't find %s in your dictionary.\n", searchTerm);
drawDashedLine();
return;
}
void caseSensSearch(char * searchTerm) {
struct Node * head = dict;
int index = 0;
while (head != NULL) {
if (strcmp(head -> word, searchTerm) == 0) {
printf("Found %s at index %i\n", head -> word, index);
drawDashedLine();
return;
}
head = head -> next;
index++;
}
printf("Sorry, I couldn't find %s in your dictionary.\n", searchTerm);
drawDashedLine();
return;
}
void search() {
int isSens;
drawDashedLine();
printf("Enter 1 for Case sensitive\n2 for case insensitive\n");
drawDashedLine();
scanf("%d", & isSens);
while (isSens < 1 || isSens > 2) {
printf("Please enter a number between 1 and 2:\n");
scanf("%d", & isSens);
}
drawDashedLine();
printf("Enter a word to search for:\n");
char searchTerm[5];
scanf("%s", searchTerm);
searchTerm[4] = '\0';
if (isSens == 1) {
caseSensSearch(searchTerm);
} else {
caseInsensSearch(searchTerm);
}
}
int promptUser() {
drawStarLine();
printf("1) Search for a word\n2) Add word(s)\n3) Print dictionary\n4) Start new dictionary\n5) Exit\n");
drawStarLine();
printf("\nEnter a number between 1 and 5:\n");
int choice;
scanf("%1d", & choice);
while (choice < 1 || choice > 5) {
printf("Please enter a number between 1 and 5:\n");
scanf("%d", & choice);
}
return choice;
}
int main() {
for (;;) {
int choice = promptUser();
fflush(stdin);
if (choice == 1) {
search();
} else if (choice == 2) {
createDict();
} else if (choice == 3) {
printDict();
} else if (choice == 4) {
destroyDict();
} else if (choice == 5) {
return 0;
}
}
return 1;
}
I've spent some time diagnosing this problem for you. The problem statement is bizarre... An array of words could be sorted (even with library qsort()) and grow to the fill the array to the brim, but you claim this must use both a linked list and a global "object pool" that is not dynamically allocated...
Here's some code I've compiled BUT NOT TESTED...
It should be simple to follow and expand to accommodate your requirements.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node { // use 'typdef'. Less typing
char word[5]; // VERY SHORT WORDS guaranteed
struct Node *next;
} Node_t;
Node_t dict[ 1000 ]; // global data space
int nextNode = 0;
void printDict() { // traverse LL outputting value(s)
for( Node_t *pn = dict; pn; pn = pn->next )
puts( pn->word );
}
void addNode( char *data ) {
if( nextNode + 1 >= sizeof dict/sizeof dict[0] )
return; // Fixed size cannot grow.
Node_t *pn = &dict[ nextNode ];
strcpy( pn->word, data ); // "apple" WON'T fit
nextNode++;
//EDIT:
// This is not correct.
// See code block below for correction
if( nextNode +1 >= sizeof dict/sizeof dict[0] )
pn->next = NULL;
else
pn->next = &dict[ nextNode ];
}
void createDict() {
char str[5000]; // one lo-o-o-ong input string of short words
printf( "Enter word(s): \n" );
fgets( str, sizeof str, stdin );
// chop words on spaces (or tabs) and store to LL
for( char *cp = str; ( cp = strtok( cp, " \t" ) ) != NULL; cp = NULL )
addNode( cp );
}
void destroyDict() { // super simple!
memset( dict, 0, sizeof dict );
nextNode = 0;
// return; // Do not need those return(s) before final closing brace.
}
80% of any problem is the clear understanding of what the problem is to begin with.
EDIT: Realising the code must 'straddle' both array and LL, the above was not exactly correct. Below is the necessary fix to conform with a LL having a NULL next pointer at its 'tail' node.
void addNode( char *data ) {
if( nextNode + 1 >= sizeof dict/sizeof dict[0] )
return; // Fixed size cannot grow.
strcpy( dict[ nextNode ].word, data ); // "apple" WON'T fit
if( nextNode ) // at node 1 or greater
dict[ nextNode - 1 ].next = &dict[ nextNode ];
nextNode++;
}
try this
if (dict == NULL) { // If previous list does not exist, global dict pointer should point to node array
dict = words;
} else { // Else find end of current linked list and point it to the new list
struct Node *head = dict;
while (head->next != NULL) {
head = head->next;
}
struct Node *ptr = NULL;
ptr->length = strlen(word);
strcpy(ptr->word, sub);
ptr->next = NULL;
head->next = ptr;
}

Storing strings to Linked list in C

In my problem, I need to read lines from a txt file.
Each line contains student_id, name, birthdate, gender, department, and grade(class).
e.g ( 155898933;Nuh Kaplan;26/01/1998;M;ME;2 )
Then I need to store them in a Linked List.
I declared my structure as follows:
struct Node{
int id;
char name[100];
int date; //YYYYMMDD (String date will be converted to integer. I created dateStrInt function for this conversion.)
char gender[2];
char departmentCode[6];
int classGrade;
struct Node *next;
};
Then I read lines and store in an character array with this part of code:
if (fptr != NULL) {
while (fgets (buff, 100, fptr)) {
char* split = strtok(buff, ";");
while( split != NULL ) {
strcpy(arr[i][j], split);
j++;
split = strtok(NULL, ";");
}
i++;
j = 0;
}
}
After I stored lines into character array, I need to store them in a linked list. I tried to do it as follows:
for(int i = 0; i < len; i++) {
p = (struct Node*) malloc(sizeof(struct Node));
j = 0;
p->id = (int)arr[i][j];
strcpy(p->name, arr[i][j+1]);
p->date = dateStrInt(arr[i][j+2]);
strcpy(p->gender,arr[i][j+3]);
strcpy(p->departmentCode, arr[i][j+4]);
p->classGrade = (int)arr[i][j+5];
j = 0;
if(list == NULL){
list = p;
p -> next = NULL;
last = p;
}
else {
last -> next = p;
p -> next = NULL;
last = p;
}
}
However when I run my code, I get garbage values for student id and classGrade.
Can you help me to solve this problem?
My hole code:
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
#include <ctype.h>
struct Node {
int id;
char name[100];
int date; //YYYYMMDD
char gender[2];
char departmentCode[6];
int classGrade;
struct Node *next;
};
int dateStrInt(char str[]) {
int d, m, y;
sscanf(str, "%d/%d/%d", &d, &m, &y);
return (y * 10000 + m * 100 + d);
}
int countLines(char* filename) {
int count = 0;
FILE *fptr;
fptr = fopen(filename, "r");
if(fptr == NULL){
printf("File does not exist.");
exit(1);
}
else {
for(char ch = getc(fptr); ch != EOF; ch = getc(fptr)) {
if(ch == '\n'){
count++;
}
}
}
return count + 1;
}
struct Node* createList(struct Node* list, int len, char filename[]){
struct Node* last;
struct Node* p;
char buff[100];
char arr[len][6][100];
int i = 0, j = 0;
FILE* fptr = fopen(filename,"r");
if (fptr != NULL) {
while (fgets (buff, 100, fptr)) {
char* split = strtok(buff, ";");
while( split != NULL ) {
strcpy(arr[i][j], split);
j++;
split = strtok(NULL, ";");
}
i++;
j = 0;
}
}
int o = 0;
for(int k = 0; k < len; k++){
printf("\nID = %s", arr[k][o]);
printf("\nName = %s", arr[k][o+1]);
printf("\nBirth Date = %s", arr[k][o+2]);
printf("\nGender = %s", arr[k][o+3]);
printf("\nDepartment = %s", arr[k][o+4]);
printf("\nGrade = %s", arr[k][o+5]);
o = 0;
}
for(int i = 0; i < len; i++){
p = (struct Node*) malloc(sizeof(struct Node));
j = 0;
p->id = (int)arr[i][j];
strcpy(p->name, arr[i][j+1]);
p->date = dateStrInt(arr[i][j+2]);
strcpy(p->gender,arr[i][j+3]);
strcpy(p->departmentCode, arr[i][j+4]);
p->classGrade = (int)arr[i][j+5];
j = 0;
if(list == NULL){
list = p;
p -> next = NULL;
last = p;
}
else {
last -> next = p;
p -> next = NULL;
last = p;
}
}
return list;
}
void printList(struct Node *list, int len){
struct Node *p;
p = list;
int cnt = 0;
printf("\nThe list = ");
while(p != NULL) {
if(cnt != len - 1) {
printf("\n{%d, %s, %d, %s, %s, %d} ---->",p->id, p->name, p->date,
p->gender, p->departmentCode, p->classGrade);
cnt++;
}
else
printf("\n{%d, %s, %d, %s, %s, %d} ",p->id, p->name, p->date,
p->gender, p->departmentCode, p->classGrade);
p = p->next;
}
}
int main(void) {
struct Node *head = NULL;
char filename[10];
printf("Enter file name: ");
scanf("%s", filename);
int len = countLines(filename);
struct Node* list = createList(head, len, filename);
printList(list, len);
}
test.txt file :
149875280;Burcu Aksu;04/04/1994;F;CS;3
180201201;Mustafa Kursat Yavuz Tur;12/06/1996;M;CS;3
Output:
Enter file name: test.txt
ID = 149875280
Name = Burcu Aksu
Birth Date = 04/04/1994
Gender = F
Department = CS
Grade = 3
ID = 180201201
Name = Mustafa Kursat Yavuz Tur
Birth Date = 12/06/1996
Gender = M
Department = CS
Grade = 3
The list =
{-1883589280, Burcu Aksu, 19940404, F, CS, -1883588780} ---->
{-1883588680, Mustafa Kursat Yavuz Tur, 19960612, M, CS, -1883588180}
Why are you declaring char array, instead you should be creating array of Node type. Just typecasting the string value to int will not convert the 2 integer fields correctly. Use the conversion function like atoi().
Change this line,
p->id = (int)arr[i][j];
to
p->id = atoi(arr[i][j]);

Read from file to linked list C

I'm new to the C language, and I'm trying to make a calendar using SDL2, but for some reason my code just skips storing the first data. When I try to return with the "head" of my linked list (which stores structures), some of the data is saved, but some is not. I have a function called linecutter. It should work fine according to my tests. The structure of the file is something like
for some reason the comment part returns correctly. If I printf the location data, it returns correctly, but otherwise it doesn't work as intended.
An examle of a file used:
Prog spec;2020/10/05;2020/11/01;00/00;23/59;Infoc;shouldnt forget it and leave to the last min
something;2020/10/05;2020/11/01;00/00;23/59;location;just a comment
asd asd;2020/2/02;2020/9/01;00/00;23/59;Infoc;lkasjd laksdj
This code should print the event names twice. Once when reading the file, once when checking in the main. But it only prints when reading.
#include <stdio.h>
#include <stdlib.h>
typedef struct Date{
int y;
int m;
int d;
} Date;
typedef struct Time{
int h;
int m;
} Time;
typedef struct Event{
char* name;
Date startdate;
Date enddate;
Time starttime;
Time endtime;
char* location;
char* comment;
} Event;
typedef struct Lista{
Event event;
struct Lista * next;
} Lista;
Date datecreate(char*todate)
{
Date *tmp = (Date *)malloc(sizeof(Date)*1);
int len = strlen(todate);
char date[len];
strcpy(date,todate);
char y[5];
char m[5];
char d[4];
int i =0;
for(; i<4; i++)
y[i] = date[i];
i++;
for(int var = 0; i<7; var++, i++)
{
m[var] = date[i];
}
i++;
for(int var = 0; i<10; var++, i++)
{
d[var] = date[i];
}
tmp->d = atoi(d);
tmp->m = atoi(m);
tmp->y = atoi(y);
return *tmp;
}
Time timecreator(char*totime)
{
Time tmp;
char h[3];
char m[3];
for(int i = 0; i<2; i++)
h[i] = totime[i];
for(int i = 4; i<6; i++)
m[i-4] = totime[i];
h[3] = '\0';
m[3] = '\0';
tmp.h = atoi(h);
tmp.m = atoi(m);
return tmp;
}
Event linecutter(char* line)
{
int i = -1;
int loc = 0;
char name[256], startdate[12],enddate[12],starttime[7],endtime[7],location[256],comment[512];
do{
i++;
name[i] = line[loc];
loc++;
}
while(name[i] !=';');
name[i] = '\0';
i=-1;
do{
i++;
startdate[i] = line[loc];
loc++;
}
while(startdate[i] !=';');
startdate[i] = '\0';
i=-1;
do{
i++;
enddate[i] = line[loc];
loc++;
}
while(enddate[i] !=';');
enddate[i] = '\0';
i=-1;
do{
i++;
starttime[i] = line[loc];
loc++;
}
while(starttime[i] !=';');
starttime[i] = '\0';
i=-1;
do{
i++;
endtime[i] = line[loc];
loc++;
}
while(endtime[i] !=';');
endtime[i] = '\0';
i=-1;
do{
i++;
location[i] = line[loc];
loc++;
}
while(location[i] !=';');
location[i] = '\0';
i=-1;
do{
i++;
comment[i] = line[loc];
loc++;
}
while(comment[i] !='\0');
comment[i] = '\0';
Event tmp;
tmp.name = name;
tmp.location = location;
tmp.comment = comment;
tmp.starttime = timecreator(starttime);
tmp.startdate = datecreate(startdate);
tmp.enddate = datecreate(enddate);
tmp.endtime = timecreator(endtime);
return tmp;
}
Lista * read(void)
{
FILE *fp;
char line[5000];
fp = fopen("esemenyek.txt" , "rw+");
if(fp == NULL) {
perror("error opening");
return NULL;
}
char buf[3];
fscanf(fp, "%3c", buf);
if (memcmp(buf, "\xEF\xBB\xBF", 3) != 0) //this is just for the encoding stuff
fseek(fp, 0, SEEK_SET);
/* ... handling the file ... */
Lista * head= NULL;
Lista * current = NULL;
while(fgets(line, sizeof(line), fp)!=NULL){
Lista *node = (Lista*)malloc(sizeof(Lista));
if(node == NULL)
{
perror("error");
return NULL;
}
node->event = linecutter(line);
node->next =NULL;
if(head== NULL){
current = head = node;
} else {
current = current->next= node;
}
for(int i = 0; i<500; i++)
line[i] ='\0';
printf("%s\n", current->event.name);
}
fclose(fp);
return head;
}
int main(void){
Lista * lst = read();
Lista *move;
for (move= lst; move!= NULL; move= move->next)
printf("%s\n", move->event.name);
return 0;
}
What am I doing wrong, or why is this not working? If someone could help me, I'd really appreciate it. I found another post here, it helped me to get here, but I don't know how to proceed from here.

nested linked list print issue

When I running this code and call " List() "function it prints only the last added by user . I want to print from beginning to the end.I hope you will help me about my list function.It prints only the last one.
#include<stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
struct seat {
int k_no;
int k_name;
struct seat *next_k, *previous_k;
} *first_k, *temp_k, *last_k;
struct sefer {
char name[20];
int no;
struct sefer *next, *previous;
struct seat *bus;
} *first, *last, *temp;
void list();
void seat_link(int val);
void sefer_search();
int main() {
int val;
printf ("how many names do you want to type ->");
scanf ("%d", &val);
int i;
int j;
for (i = 0; i < val; i++) {
if (first == NULL) {
first = (sefer *)malloc(sizeof(struct sefer));
fflush(stdin);
printf(" %d. name->", i + 1);
scanf("%s", &first->name);
printf(" %d. capacity ->", i + 1);
scanf("%d", &first->no);
first->next = NULL; //2 inci düğüm daha oluşmadığı için null
first->previous = NULL;
last = first; //şimdilik sadece ilk düğüm olduğu için aynı zamanda son oluo
last->bus = NULL;
for (j = 0; j < first->no; j++) {
//KOLTUKLAR OLUŞTURULCAK
if (last->bus == NULL) {
first_k = (seat *)malloc(sizeof(struct seat));
fflush(stdin);
first_k->k_no = j;
first_k->k_name = 1;
first_k->next_k = NULL;
first_k->previous_k = NULL;
last_k = first_k;
last->bus = first_k;
} else {
temp_k = (seat *)malloc(sizeof(struct seat ));
fflush(stdin);
temp_k->k_no = j;
temp_k->k_name = 0;
last_k->next_k = temp_k;
temp_k->previous_k = last_k;
last_k = temp_k;
last_k->last_k = NULL;
}
}
} else if (last == first) {
printf("\n");
last = (sefer *)malloc(sizeof(struct sefer));
fflush(stdin);
printf(" %d. name ->", i + 1);
scanf("%s", &last->name);
printf(" %d. capacitiy ->", i + 1);
scanf("%d", &last->no);
first->next = last;
last>next = NULL;
last->previous = first;
last->bus = NULL;
for (j = 0; j < last->no; j++) {
//KOLTUKLAR OLUŞTURULCAK
if (last->bus == NULL) {
first_k = (seat *)malloc(sizeof(struct seat ));
fflush(stdin);
first_k->k_no = j;
first_k->k_name = 2;
first_k->last_k = NULL;
first_k->previous_k = NULL;
last_k = first_k;
last->bus = first_k;
} else {
temp_k = (seat *)malloc(sizeof(struct seat));
fflush(stdin);
temp_k->k_no = j;
temp_k->k_name = 0;
last_k->next_k = temp_k;
temp_k->previous_k = last_k;
last_k = temp_k;
last_k->last_k = NULL;
}
}
} else { // kayıt eklenmişse diğer düğümler oluşturulcak
printf ("\n");
temp = (sefer *) malloc(sizeof(struct sefer));
fflush(stdin);
printf(" %d. name", i + 1);
scanf("%s", &temp->name);
printf(" %d. capacity->", i + 1);
scanf("%d", &temp->no);
last->next = temp;
temp->previous = last;
last = temp;
last->next = NULL;
last->bus = NULL;
for (j = 0; j < temp->no; j++) {
//KOLTUKLAR OLUŞTURULCAK
if (last->bus == NULL) {
first_k = (seat*)malloc(sizeof(struct seat));
fflush(stdin);
first_k->k_no = j;
first_k->k_name = 3;
first_k->last_k = NULL;
first_k->previous_k = NULL;
last_k = first_k;
last->bus = first_k;
} else {
temp_k = (seat *)malloc(sizeof(struct seat));
fflush(stdin);
temp_k->k_no = j;
temp_k->k_name = 0;
last_k->next_k = temp_k;
temp_k->previous_k = last_k;
last_k = temp_k;
last_k->next_k = NULL;
}
}
}
}
list();
system("PAUSE");
return 0;
}
void sefer_search() { //bağda arama yapar
int searching;
printf("\n\t\t Aranacak Sefer Numarasını Giriniz:");
scanf("%d", &searching);
temp = first;
while (1) {
if (temp->no == searching) {
break;
}
temp = temp->next;
}
}
void seat_link(int val) {
int j;
}
my problem is here actually :
void list() {
temp = first;
while (temp != NULL) {
printf("\t%s --%d \n", temp->name, temp->no);
temp = temp->next;
}
printf ("\n");
last->bus = first_k;
while (last->bus != NULL) {
printf("\t%d --%d \n", last->bus->k_name, last->otobus->k_no);
last->bus = last->bus->next_k;
}
}
Please help me
There are a bunch of problems with your code. Firstly, it won't compile for various reasons. For instance, you sometimes use a struct koltuk without ever defining it. "koltuk" means "seat" in Turkish, so I'm going to assume you meant struct seat in all those cases. Secondly, deg is undefined; I assume you meant val.
There were a few other problems like that which I was able to fix by making plausible guesses. But that leaves the following fundamental problems:
You are using global variables as local variables, for instance temp_k and temp. This makes it well-nigh impossible for a human to analyze your code and understand the control flow.
You have copied code all over the place. You have three separate code blocks to allocate and initialize a sefer depending upon whether it's first in the global linked list, second, or later. Use subroutines!
Your data model seems confused. You have global variables struct *first_k,*temp_k,*last_k; which makes it seem like you have one global linked list of seats for all sefer structs, but the struct seat does not refer back in an obvious way to the sefer that owns it, which implies that each sefer has a separate, private list of seats.
Taking all three problems together, I can't really see where, specifically, you are going wrong. I took a cut at rewriting your code to eliminate these problems. Give it a try to see if it solves your problems:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
typedef struct seat{
int k_no;
int k_name;
struct seat *next_k, *previous_k;
} seat;
typedef struct sefer {
char name[20];
int no;
struct sefer *next,*previous;
struct seat *bus;
} sefer;
void list();
sefer *sefer_search();
void link_sefer(sefer **pp_first, sefer **pp_last, sefer *p_added)
{
p_added->next = p_added->previous = NULL;
if (*pp_first == NULL)
{
*pp_first = *pp_last = p_added;
}
else
{
(*pp_last)->next = p_added;
p_added->previous = *pp_last;
*pp_last = p_added;
}
}
void link_seat(seat **pp_first, seat **pp_last, seat *p_added)
{
p_added->next_k = p_added->previous_k = NULL;
if (*pp_first == NULL)
{
*pp_first = *pp_last = p_added;
}
else
{
(*pp_last)->next_k = p_added;
p_added->previous_k = *pp_last;
*pp_last = p_added;
}
}
sefer *create_and_link_sefer(sefer **pp_first_sefer, sefer **pp_last_sefer, int i)
{
sefer *new_sefer;
seat *p_first_seat = NULL;
seat *p_last_seat = NULL;
int j;
// Allocate and initialize sefer
printf ("\n");
new_sefer = calloc(1, sizeof(struct sefer));
fflush(stdin);
printf (" %d. name->",i+1);
scanf ("%s",&new_sefer->name);
printf (" %d. capacity->",i+1);
scanf ("%d",&new_sefer->no);
new_sefer->bus = NULL;
// Link sefer
link_sefer(pp_first_sefer, pp_last_sefer, new_sefer);
// Allocate seats
for(j=0;j<new_sefer->no;j++){
//KOLTUKLAR OLUŞTURULCAK
seat *p_seat = calloc(1, sizeof(struct seat));
fflush(stdin);
p_seat->k_no=j;
p_seat->k_name = (j != 0 ? 0 : (i+1 > 3 ? 3 : i+1)); // I CAN'T FIGURE OUT WHAT THIS IS SUPPOSED TO BE
link_seat(&p_first_seat, &p_last_seat, p_seat);
}
new_sefer->bus = p_first_seat;
return new_sefer;
}
void sefer_list(sefer *first, sefer *last){
sefer *temp=first;
while (temp !=NULL)
{
seat *seat;
printf("\t%s --%d \n", temp->name,temp->no);
for (seat = temp->bus; seat != NULL; seat = seat->next_k)
{
printf("\t\t%d --%d \n",seat->k_name, seat->k_no);
}
printf ("\n");
temp=temp->next;
}
}
sefer *sefer_search(sefer *first, sefer *last){ //bağda arama yapar
int arama;
sefer *temp;
printf ("\n\t\t Aranacak Sefer Numarasını Giriniz:");
scanf ("%d",&arama);
temp=first;
while (temp != NULL){
if (temp->no==arama){
break;
}
temp=temp->next;
}
return temp;
}
sefer *first = NULL;
sefer *last = NULL;
int main( )
{
int val;
int i;
printf ("how many names do you want to type ->");
scanf ("%d",&val);
for(i=0;i<val;i++){
create_and_link_sefer(&first, &last, i);
}
sefer_list(first, last);
system("PAUSE");
return 0;
}
It seems to work, but since I don't know what you are trying to do, it might not be working as you want.
Judging by the logic, that means that temp really isn't going anywhere. My guess is that when you set those pointers *first, *last, *temp; in the first few lines of main, you don't really point first to NULL, causing it to skip the first if statement. Pointers don't point to NULL by default, they point to whatever was at that memory location beforehand. In this case, garbage. Try adding first=NULL; prior to your first if-statement.

Hashing, linked list, delete node

My task is to delete a node from a array of pointers which point to structure.
My code doesn't work and I just don't know why:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Jmena4.h"
#define LENGTH 101
#define P 127
#define Q 31
typedef struct node {
char *name;
struct uzel *next;
} NODE;
int hash(const char Name[]) {
int i;
int n = strlen(Name);
int result;
result = Name[0] * P + Name[1] * Q + Name[n - 1] + n;
return result % LENGTH;
}
void Insert(NODE *array[], const char *name) {
NODE *u;
int h;
u = (NODE*)malloc(sizeof(NODE));
u->name = name;
h = hash(name);
u->next = array[h];
array[h] = u;
}
int Search(NODE *array[], const char *name) {
NODE *u;
u = array[hash(name)];
while (u != NULL) {
if (strcmp(u->name, name) == 0) {
printf("%s\n", u->name);
return 1;
}
u = u->next;
}
printf("Name: %s wasn't found\n", name);
return 0;
}
int Delete(NODE *array[], const char *name) {
NODE *current;
NODE *previous;
int position = hash(name);
current = array[position];
previous = NULL;
while (current != NULL) {
if (strcmp(current->name, name) == 0) {
if (previous == NULL) {
array[position] = current->next;
return 1;
} else {
previous->next = current->next;
current = NULL;
return 1;
}
}
previous = current;
current = current->next;
}
return 0;
}
int main() {
int i;
NODE *array[LENGTH];
for (i = 0; i < LENGTH; i++) {
array[i] = NULL;
}
for (i = 0; i < Pocet; i++) {
Insert(array, Jmena[i]);
}
for (i = 0; i < PocetZ; i++) {
Delete(array, JmenaZ[i]);
}
Search(array, "Julie");
system("PAUSE");
return 0;
}
EDIT 1: I changed names of variables and instead of position = array[position] should be current = array[position], but it still doesn't work.
EDIT 2 : In array Jmena is string "Julie" and I can search it after Insert function, but after I delete strings from JmenaZ which not included "Julie" program output is: Name: Julie wasn't found.
For one thing, current isn't initialized before it gets tested in the while loop.

Resources