I'm trying to use linked lists to store the data from the periodic table: name, symbol, and atomic weight. My code is printing correctly for some elements, but the element name is disappearing sometimes. Running the same code multiple times, it's not printing different names at different times. (I messed up the order while giving the inputs, but please ignore that.)
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include <string.h>
typedef struct list{char element[20]; char sym[20];float weight;struct list*next;}list;
int printlist(list *h, char *title){
printf("%s\n", title);
while(h!=NULL){
printf("%s: %s: %f \n", h->element, h->sym, h->weight);
h = h-> next;
}
}
list* create_list(char e[], char s[], float w){
list * head = malloc(sizeof(list));
strcpy(head->element,e);
strcpy(head -> sym,s);
head -> weight = w;
head -> next = NULL;
return head;
}
void add_to_rear(char e[], char s[], float w, list*h){
while(h->next != NULL){
h= h-> next;
}
list *nn = create_list(e, s, w);
h -> next = nn;
}
int main(){
list list_of_atoms;
list * head = NULL;
for(int i=0; i<1;i++){
printf("element %d", i+1);
char el[20];
char symbol[2];
float atwt;
scanf("%s", el);
scanf("%s", symbol);
scanf("%f", &atwt);
head = create_list(el, symbol, atwt);
}
for(int i=1; i<10;i++){
printf("element %d", i+1);
char el[20];
char symbol[2];
float atwt;
scanf("%s", el);
scanf("%s", symbol);
scanf("%f", &atwt);
add_to_rear(el, symbol, atwt, head);
}
printlist(head, "First 10 elements");
return 0;
}
You allocate and fill in a bunch of list
s (which is a misnomer; each struct is actually info about an element) and then discard them ... head
ends up pointing to the last element entered, and its next
field is NULL
. You then read in all the elements again (why?), scanning each time to the end of the list and appending the element--which is an O(N*N) operation. (I suspect that you actually entered an empty list for the first loop, and then entered your 10 elements for the second loop, but it's impossible to tell because you provided the input as a truncated screen shot. Please don't do that. Instead, copy the text from your CMD window.) Edit: Now I see that your first loop actually only runs one time. It's like you wrote it one way, then changed your mind and wrote it another way, but left the old code there.
The reason the output is wrong is that you are using scanf
to read 2-character symbols plus a terminating NUL into symbol[2]
, which isn't big enough. This is undefined behavior, but what it is probably doing is overwriting the first byte of the element name with a NUL. Notice that all the elements with 2-letter symbols are missing the element name and the ones with 1-letter symbols are not.