Reputation: 31
My task is to create program that reads all the words from file and puts into output file those words, that are identical from beginning to end (i mean aha, oho, asdsa, assa, etc). And task requires usage of dynamic memory (university), but I have been stuck in this place for days because I can't find why it doesn't want to do what I intend to do. I have 4 words in file. Those 4 printfs should print all words, but my program prints 3rd word, (null) and segmentation error. I use one-sided dynamic memory. Please explain why it doesn't work, because I can't do it myself. Thank you in advance! Code:
/*
* Task: Write program, that finds all words from file which reads from beginning to end (lets call them mirror-type words)
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct elements
{
char str[255];
struct elements *next;
};
/* Function checks if given word is mirror-type word */
int is_mirror(char str[255])
{
int length = strlen(str);
int to = (length % 2 == 1) ? (length - 1) / 2 : length / 2;
int i = 0;
while (i < to)
{
if (str[i] != str[length-i-1]) return 0;
i++;
}
return 1;
};
int main()
{
FILE *in;
in = fopen("3_12.in", "r");
if (in == NULL)
{
printf("Input file doesnt exist.\r\n");
return 0;
}
char str[255];
fscanf(in, "%s", str);
struct elements *beginning, *element;
element = (struct elements *) malloc(sizeof(struct elements));
strcpy(element->str, str);
beginning = element;
do
{
fscanf(in, "%s", str);
element->next = (struct elements *) malloc(sizeof(struct elements));
strcpy(element->str, str);
if (feof(in))
{
element->next = NULL;
break;
}
}
while(1);
printf("%s\r\n", element->str);
printf("%s\r\n", element->next->str);
printf("%s\r\n", element->next->next->str);
printf("%s\r\n", element->next->next->next->str);
fclose(in);
}
Upvotes: 0
Views: 135
Reputation: 40145
change
beginning = element;
do
{
fscanf(in, "%s", str);
element->next = (struct elements *) malloc(sizeof(struct elements));
strcpy(element->str, str);
if (feof(in))
{
element->next = NULL;
break;
}
}
while(1);
printf("%s\r\n", element->str);
printf("%s\r\n", element->next->str);
printf("%s\r\n", element->next->next->str);
printf("%s\r\n", element->next->next->next->str);
to
beginning = element;
while(EOF!=fscanf(in, "%s", str)){
element->next = (struct elements *) malloc(sizeof(struct elements));
element = element->next;
strcpy(element->str, str);
}
element->next = NULL;
printf("%s\n", beginning->str);
printf("%s\n", beginning->next->str);
printf("%s\n", beginning->next->next->str);
printf("%s\n", beginning->next->next->next->str);
and add palindrome check.
Upvotes: 0
Reputation: 2427
Looking at your code it looks likes you missed a step in your loop. You never advance passed the second word because element is never updated.
Code Snippet
do
{
fscanf(in, "%s", str); //Get the string
element->next = (struct elements *) malloc(sizeof(struct elements)); //Create a new element at the end of the list
element = element->next; //Move forward to the newly created element
strcpy(element->str, str); //Copy the read string into the newly create element's `str`
//If we've hit the end of the file, put a null at the end of the list and break
if (feof(in))
{
element->next = NULL;
break;
}
}
while(1);
Check out this page it has some great information on linked lsits (which is what you're using).
Edit 1
I noticed an error with the original code I had written. Where str
is set it was overwriting the original element's str
value. The code would never create a list longer than 1 element and that one element would always have the last word in the file followed by a null.
Upvotes: 1
Reputation: 73366
Here is how it should be with two words to be read.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct elements {
char str[255];
struct elements *next;
};
int main() {
FILE *in;
in = fopen("test.txt", "r");
if (in == NULL) {
printf("Input file doesnt exist.\r\n");
return 0;
}
char str[255];
fscanf(in, "%s", str);
struct elements *beginning, *element;
element = malloc(sizeof(struct elements));
strcpy(element->str, str);
element->next = NULL;
beginning = element;
do {
fscanf(in, "%s", str);
element = malloc(sizeof(struct elements));
strcpy(element->str, str);
element->next = NULL;
beginning->next = element;
if (feof(in)) {
break;
}
} while (1);
printf("%s\r\n", beginning->str);
printf("%s\r\n", beginning->next->str);
fclose(in);
free(beginning->next);
free(beginning);
}
The test.txt
aabb
sam
So, you are trying to build one linked list. I create in the above example one node, set the first word read to it element->str
, and element->next
to NULL.
Then I set the beginning
to that node. Note that instead of beginning
, people usually use head, since it's the first node of the list.
Then I do the same thing for the next word and I am inserting the new node as the second node of the list.
You see that you need to build a list, because this is getting big. I learnt how to do that through this code.
Do not cast what malloc() returns.
Upvotes: 0