C Why does this loop through the first item? [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
I'm loading in a file:
05 11 2014 14 53 00
AB01 52.408 -4.217
XY23 51.750 -4.300
PQ29 52.100 -6.000
NY23 52.000 -5.900
The first line gets put into a dateTime struct. My code is then supposed to loop through the rest of the lines, putting them into a linked list of structs. However, it creates a linked list of the same element in an infinite loop.
typedef struct observer{
char id[21];
float lat;
float longitude;
struct observer *next;
} observer;
printf("Please enter the name of the observer file: ");
scanf("%s", fileName);
FILE* f1 = fopen(fileName, "r");
if(f1 == NULL)
{
perror("Error opening file");
return;
}
fscanf(f1, "%d %d %d %d %d %d", &dateTime.date, &dateTime.month,
&dateTime.year, &dateTime.hour, &dateTime.minute, &dateTime.second);
while(fscanf(f1, "%s %f %f", temp_id, &temp_lat, &temp_long))
{
struct observer *new_obs = make_observer(temp_id, temp_lat, temp_long);
insert_observer(new_obs, &observer_start);
print_observer(&observer_start);
}
fclose(f1);
observer* make_observer(char *id, float lat, float longitude)
{
observer *node = (observer*) malloc(sizeof(observer));
strcpy(node->id, id);
node->lat = lat;
node->longitude = longitude;
node->next = NULL;
return node;
}
void insert_observer(observer *node, observer **list)
{
observer *current;
observer *previous = NULL;
//int inserted = 0;
if(*list == 0)
{
*list = node;
return;
}
current = *list;
while(current != NULL)
{
if(previous != NULL)
{
previous->next = node;
}
else
{
*list = node;
}
previous = current;
current = current->next;
}
}

Try changing your insert function to this:
void insert_observer(observer *node, observer **list)
{
if (*list)
{
observer *current = *list;
observer *previous;
while (current)
{
previous = current;
current = current->next;
}
previous->next = node;
}
else
*list = node;
}
This just finds the end of the list and attaches the node to the last list item.
You also need to change the main loop while condition to check that the expected number of fields have been read:
while (fscanf(f1, "%s %f %f", temp_id, &temp_lat, &temp_long) == 3)

Related

Linked List remove node function not working properly [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 months ago.
Improve this question
When I run the program below - the output I get is
head node created
node addded with value of 22
node addded with value of 22343
node addded with value of 7
22
22343
7
last node has been removed
current last nodes value is 22343
22
22343
7
This issue is that , if the last node in the list is stated to have a data value of 22343 when the removenode function is called , how is it possble that the last value printed is 7 and not 22343 - when the traverse function is called? despite the fact that the *next pointer of the last node is set to NULL in the removenode funtion.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node_n
{
int value;
struct node *next;
};
typedef struct node_n node;
node* makeheadnode()
{
node *temp = (node*)malloc(sizeof(node));
temp->next = NULL;
temp->value = NULL;
printf("\n head node created");
return temp;
}
void addnode(node *target, int data)
{
while (target->next != NULL)
{
target = target->next;
}
target->next = (node*)malloc(sizeof(node));
target = target->next;
target->value = data;
target->next = NULL;
printf("\n node addded with value of %d ",target->value);
}
int removenode(node *target)
{
node *temp;
if(target->next == NULL)
{
printf("\n only one node is present");
return 1;
}
while(target -> next != NULL)
{
temp = target -> next;
if(temp -> next == NULL)
{
target->next == NULL;
printf("\n last node has been removed \n current last nodes value is %d",target->value);
return 1;
}
else
{
target = target-> next;
}
}
}
int traverse(node *target)
{
if(target->next == NULL)
{
printf("\n this list is empty");
return 1;
}
while (target->next != NULL)
{
target = target -> next;
printf("\n %d", target -> value);
}
return 1;
}
int main()
{
node *head = makeheadnode();
addnode(head,22);
addnode(head,22343);
addnode(head,007);
traverse(head);
removenode(head);
traverse(head);
}
The problem is a typo. In your removenode function, you have:
target->next == NULL;
Where it should be:
target->next = NULL;
If you compile with warnings on, i.e. -Wall or even -Werror, the compiler should have warned you with a message like equality comparison result unused.
Furthermore, since you're removing the node, you should free it so you don't have any memory leaks. Setting a pointer to NULL does not free the pointer. Many, including myself, also see it as good practice to set the pointer to NULL after freeing.
free(target->next)
target->next = NULL
For more info on that, see this post

Why does the root change its data? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
Here is are the three structures that I'm using and for instance when my program
gets 'the' as the first word, it makes *rt->str = the.
However when the next word is read, the key is equal to to the *rt->str and I don't understand why. I'm a c programmer beginnner and this has really stoppped me in my tracks.
struct node {
char *str;
int occ;
struct node *sibling;
struct node *child;
};
struct node* root;
struct node* getNew(char word[100]) {
struct node *newNode;
newNode = (struct node *)malloc(sizeof(struct node));
newNode->str = word;
newNode->sibling = NULL;
newNode->child = NULL;
newNode->occ = 0;
return newNode;
}
struct node* insert( char key[100], struct node **rt ){
if(*rt == NULL) {
*rt = getNew(key);
printf("This is the key in the root: %s\n", (*rt)->str);
return *rt;
}else{
printf("root word: %s\n", (*rt)->str);
exit(0);
}
struct node *leaf = *rt;
int n = 0;
int i;
char w2[100];
strcpy(w2, key);
printf("root word: %s\n", (*rt)->str);
for(i = 0; i < strlen((leaf)->str); i++) {
printf("%c %c \n", (leaf)->str[i], key[i]);
if((key[0] == (leaf)->str[i])) {
n++;
key = key + 1;
printf("key is: %s \n", key);
}
}
if(key[0] == 0) {
printf("key is empty \n");
}
printf("This is the word after for loop: %s \n", key);
exit(0);
}
This:
newNode->str = word;
doesn't copy the string (as in, the characters that build up the string), it just copies the location of a string, which is an argument. That location will not remain valid when the function exits, so this gives you undefined behavior when you access it later.
C does not support assigning arrays, and arrays are not pointers.

Expected declaration specifiers [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am learning linked lists in C. I am new to using pass by references for manipulating the linked lists. Now I know I'm doing something really foolish in this program. This program creates a list and then basically returns the number of instances of a particular value(the data of node). I get an error like so, "Expected declaration specifier" before every statement of main!.
What's going on wrong?
#include<stdio.h>
#include<malloc.h>
struct list {
int number;
struct list *next;
};
typedef struct list node;
void create(node *);
int count(node **,int);
main()
int key,this_many;
node *head;
head = (node *)malloc(sizeof(node));
create(head);
printf("Which number?\n");
scanf("%d",&key);
this_many = count(&head,key);
printf("%d times\n",this_many);
return 0;
}
void create(node *list) {
printf("Enter a number -999 to stop\n");
scanf("%d",&list->number);
if(list->number == -999) {
list->next = NULL;
}
else {
list->next = (node *)malloc(sizeof(node));
create(list->next);
}
}
int count(node **addr_list,int key) {
int count = 0;
while(*addr_list != NULL) {
if((*addr_list)->number == key) {
count++;
}
*addr_list = (*addr_list)->next;
}
return(count);
}
Problems:
You are not specifying the return type of main.
You don't have the { to start the scope of main.
Change the lines starting with main to:
int main()
{
int key,this_many;
node *head;
head = (node *)malloc(sizeof(node));
create(head);
printf("Which number?\n");
scanf("%d",&key);
this_many = count(&head,key);
printf("%d times\n",this_many);
return 0;
}

reading from a file to make an array using C [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
How do I make an array by reading from a .txt file??
I'm making a bidding(auction) program. I need to read integers from the .txt and use those in an array. I am confused as to how I would go about that in my program.
The txt is as follows:
100 15
200 20
300 25
400 30
500 35
It is definitely recommended to show one's own effort while asking the question. However, to give you a jump start, please find a couple of solutions as below.
One possible illustrative solution using a static array is as in Solution 1 below. The assumption in the solution below is that the number of elements is known and is less than 32. If wish to keep it truly dynamic, you will have to implement a solution using a linked list as in Solution 2 below.
Solution 1: Fixed Array based approach
int main()
{
FILE *finp;
int someArr[32];
int i, ctr = 0;
finp = fopen("haha.txt", "r");
if(NULL == finp)
{
printf("Unable to open file\n");
exit(-1);
}
while((!feof(finp)) && (ctr < 32))
{
fscanf(finp, "%d ", &someArr[ctr++]);
}
for(i = 0; i < (ctr -1); i++)
{
printf("%d==>", someArr[i]);
}
printf("%d\n", someArr[i]);
fclose(finp); //Close the file pointer
return 0;
}
The expected output of this program is
100==>15==>200==>20==>300==>25==>400==>30==>500==>35
Solution 2: Linked List based solution
Further to my earlier comment, please find an alternative dynamic solution which doesn't require a prior knowledge on the number of elements as below.
typedef struct node {
int value;
struct node *next;
}node;
void createList(FILE *fInp, node **headBase)
{
node *currNode;
node *head = *headBase;
node *tail;
while(!feof(fInp))
{
currNode = malloc(sizeof(struct node));
fscanf(fInp, "%d ", &currNode->value);
currNode->next = NULL;
if(NULL == head)
{
head = currNode;
tail = currNode;
}
else
{
tail->next = currNode;
tail = currNode;
}
}
//Store back the updated head pointer
*headBase = head;
}
void printList(node **headBase)
{
node *tmpNode = *headBase;
while(tmpNode->next != NULL)
{
printf("%d-->", tmpNode->value);
tmpNode = tmpNode->next;
}
printf("%d\n", tmpNode->value);
}
void deleteList(node **headBase)
{
node *head = *headBase;
node *tmp;
while(NULL != head)
{
tmp = head; // Get a temp pointer
head = head->next; // Move head pointer
tmp->next = NULL; // break the link
printf("<< Deleted Node: %d\n", tmp->value);
free(tmp);
}
// Store the head pointer back which should be NULL
*headBase = head;
}
int main()
{
FILE *finp;
node *head = NULL;
finp = fopen("haha.txt", "r");
if(NULL == finp)
{
printf("Unable to open file\n");
exit(-1);
}
createList(finp, &head);
printList(&head);
deleteList(&head);
fclose(finp);
return 0;
}
The expected output of this program is
100-->15-->200-->20-->300-->25-->400-->30-->500-->35
<< Deleted Node: 100
<< Deleted Node: 15
<< Deleted Node: 200
<< Deleted Node: 20
<< Deleted Node: 300
<< Deleted Node: 25
<< Deleted Node: 400
<< Deleted Node: 30
<< Deleted Node: 500
<< Deleted Node: 35
Supposing you don't know how many integers can be found in the input file, you could define a max value.
You must too include stdio.h and stdlib.h
#define MAX 255
int main() {
FILE *file = fopen("input.txt", "r");
int integers[MAX];
int i = 0;
if (file != NULL) {
while (!feof(file) && i < MAX) {
if (fscanf(file, "%d", &integers[i++]) != -1) {
printf("%d ", integers[i-1]);
}
}
fclose(file);
} else {
printf("Unable to open file");
return EXIT_FAILURE;
}
return 0;
}

linked list remains empty even after adding nodes? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
thanx k-ballo, u solved my prevoius problem but then i landed into another one!!
i created nodes and then tried to display them, but every time i called append_node(), the double pointer **head_ptr(used to hold the address of the very first pointer *head, which in turn, holds the address of the very first node of the linked list), was holding a NULL value as if previous calls to append_node(&head, value) didnt add any node to *head.
so whenever i display the list, it reamins empty!! :
#include <stdio.h>
struct __node
{ int data;
struct __node *next;
};
typedef struct __node node;
int append_node(node **head_ptr, int value) //double pointer head_ptr to simulate call-by-reference
{ node *temp, *q;
temp = (node *) malloc(sizeof(node));
if(!temp)
{ printf("\ninsufficient memory!!");
return -1;
}
q = *head_ptr; //as *head_ptr is address of a pointer (which is *head), so any changes made after this line in q should also be reflected in main().. (i guess so!)
temp->data = value;
temp->next = NULL;
if(q == NULL)
{ q = temp;
printf("\nq is empty");
return 0;
}
while( q->next != NULL)
{ q = q->next;
}
printf("\nq is not empty");
q->next = temp;
return 0;
}
int disp_list(node **head_ptr)
{ node *q;
int i=1;
q = *head_ptr;
if(q != NULL)
{ while( q != NULL )
{ printf("|%d-%d|--->", i++, q->data);
q = q->next;
}
}
else
{ printf("\nlist is empty!!");
}
return 0;
}
int main()
{ node *head=NULL;
int value, res, i=0;
while(i<3)
{ printf("\nenter the data to be inserted into the node: ");
scanf("%d", &value);
res = append_node( &head, value);
i++;
}
printf("\nprinting all the nodes...\n") ;
res = disp_list(&head);
printf("\n---------------\nexiting...\n\n\n");
return 0;
}
i know i could have returned *q from append_node() and reassigned it to *head or declared *head as global.. but i want to *head to be manipulated by so-called-pass-by-reference method only. (theres no pass-by-reference actually in c!) my compiler is: gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4)
plz help..i m not an expert so please use easier terminology!! :p
Your initial call to append_node is passing a pointer to a pointer to node which is uninitialized (let's pressume its null, though it will probably be just garbage). Then you do
q = *head_ptr;
//above statement causes a segment fault error..
// that statement should be fine, we will get the value of main's head, which we pressume to be null
// now we will try to dereference null by accesing its next element
while( q->next != NULL)
{ q = q->next;
}
There are two major problems with this program:
head is not initialized and contains garbage.
You don't handle the case of an empty list in append_node().
Both problems will lead to segmentation fault errors.

Resources