This is the one of main part of the code that the pls format file should convert to m3u format song under numbers of seconds which specified :
[playlist]
NumberOfEntries=3
File1=C:\muzika\Chris Rea - Looking For The Summer.mp3
Title1=Chris Rea - Looking For The Summer
Length1=302
File2=C:\muzika\Simply Red - Holding Back The Years.mp3
Title2=Simply Red - Holding Back The Years
Length2=265
File3=C:\muzika\Mambo Kings - Luz de luna.mp3
Title3=Mambo Kings - Luz de luna
Length3=207
Version=2
convert to:
#EXTINF:207,Mambo Kings - Luz de luna
C:\muzika\Mambo Kings - Luz de luna.mp3
#EXTINF:265,Simply Red - Holding Back The Years
C:\muzika\Simply Red - Holding Back The Years.mp3
.
if ( file != NULL )
{
char line[256];
while (fgets(line, sizeof line, file) != NULL)
{
if (count == lineNumber)
{
int j=0;
if (line[0] == 'F') {
int brojac=6;
while(line[brojac]!='\n'){
ffolder[j]=line[brojac];
j++;
brojac++;
}
folder=ffolder;
}
if (line[0] == 'T') {
int brojac=7;
while(line[brojac]!='\n'){
naslov1[j]=line[brojac];
j++;
brojac++;
}
naslov=naslov1;
}
if (line[0] == 'L') {
int brojac=8;
while(line[brojac]!='\n'){
vremee[j]=line[brojac];
j++;
brojac++;
}
vreme=vremee;
//intvreme = folder11(line);
if(atoi(vremee)<atoi(argv[3])) {
//fprintf(out, "\n#EXTINF:%s,%s\n%s", vremee,naslov1,ffolder);**key part**
struct pesma *link = (struct pesma *) malloc(sizeof(struct pesma));
link->folder = folder;
printf("%s\n",folder);
link->naslov = naslov;
printf("%s\n",naslov);
link->vreme = atoi(vreme);
link->next = NULL;
if (!glava) {
glava = link;
} else {
struct pesma *tail = glava;
while (tail->next) {
tail = tail->next;
}
tail->next = link;
}
}
}
}
else
{
count++;
}
}
}
When I call the function that should print the elements of the linked list, for each song that meets the criteria, print this:
#EXTINF:207,Mambo Kings - Luz de luna
C:\muzika\Mambo Kings - Luz de luna.mp3
#EXTINF:265,Mambo Kings - Luz de luna
C:\muzika\Mambo Kings - Luz de luna.mp3
vreme is normal,but folder and naslov are from last last line in file.
However, if I use the fprintf function (in the key part in the main code) instead of a concatenated list, the printout is correct, but then I can't sort alphabetically.
fprintf(out, "\n#EXTINF:%s,%s\n%s", vremee,naslov1,ffolder);
I'm wondering why the linked list is printed like this?
my guess - cant do better since we have an incomplete program
link->folder = folder;
link is a char * member. If so you should do
link->folder = strdup(folder);
otherwise they all end up pointing to the buffer 'folder' and whatever it last contained
Your application modified so that it reads the input data into a linked list. Using char arrays in the song struct makes them easier to handle. For sorting the list insertion sort is used.
There remains some work to do with this code:
Extract duplicate code into functions
Complete error handling, a.o. check all function return values
Maybe use a command line argument for the input file name
In general, try to use English words for names (data structures, functions, variables, etc.).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE_LENGTH 256
typedef struct song { // pesma
char file[MAX_LINE_LENGTH];
char title[MAX_LINE_LENGTH]; // naslov
int time; // vreme
struct song * next;
} SONG;
// Insertion Sort
SONG * sort_songs(SONG * root) {
if (root == NULL || root->next == NULL) {
// All lists with less than two elements are already sorted.
return root;
}
// put first element into sorted list
SONG * sorted_root = root;
// start iteration with second element
SONG * iterator = root->next;
// set end of sorted list
sorted_root->next = NULL;
while (iterator != NULL) {
// trace position directly before insertion point
SONG * previous = NULL;
// iterate over already sorted list
SONG * sorted_iterator = sorted_root;
// determine insertion point in already sorted list
while (
// list end not reached
sorted_iterator != NULL
&&
// need to advance in sorted list for proper position
strcmp(sorted_iterator->title, iterator->title) <= 0) {
previous = sorted_iterator;
sorted_iterator = sorted_iterator->next;
}
if (previous == NULL) {
// prepend sorted list with element
SONG * tmp = sorted_root;
sorted_root = iterator;
iterator = iterator->next;
sorted_root->next = tmp;
} else if (sorted_iterator == NULL) {
// append new last element in sorted list
previous->next = iterator;
SONG * tmp = iterator->next;
iterator->next = NULL;
iterator = tmp;
} else {
// insert element at correct position
SONG * tmp = iterator->next;
previous->next = iterator;
iterator->next = sorted_iterator;
iterator = tmp;
}
}
return sorted_root;
}
int main()
{
char line[MAX_LINE_LENGTH];
char *filename = "playlist.txt";
// pointer to first element of the linked song list
SONG *root = NULL; // glava
FILE *file = fopen(filename, "r");
if (file == NULL) {
fprintf(stderr, "Could not open file '%s'!\n", filename);
return EXIT_FAILURE;
}
// read line containing "[playlist]"
fgets(line, sizeof line, file);
// read line containing "NumberOfEntries=3"
fgets(line, sizeof line, file);
char *start_position = strchr(line, '=') + 1;
int number_of_entries = atoi(start_position);
printf("Number of entries: %d\n", number_of_entries);
for (int i = 0; i < number_of_entries; i++) {
// allocate new node for linked list and put it to the front of the list
SONG *node = malloc(sizeof(SONG));
node->next = root;
root = node;
// read file name
if (fgets(line, sizeof line, file) == NULL) {
fprintf(stderr, "Unexpected end of file!\n");
fclose(file);
// TODO: release allocated memory
return EXIT_FAILURE;
}
start_position = strchr(line, '=') + 1;
strcpy(node->file, start_position);
node->file[strlen(start_position) - 1] = '\0';
// read title
if (fgets(line, sizeof line, file) == NULL) {
fprintf(stderr, "Unexpected end of file!\n");
fclose(file);
// TODO: release allocated memory
return EXIT_FAILURE;
}
start_position = strchr(line, '=') + 1;
strcpy(node->title, start_position);
node->title[strlen(start_position) - 1] = '\0';
// read time
if (fgets(line, sizeof line, file) == NULL) {
fprintf(stderr, "Unexpected end of file!\n");
fclose(file);
// TODO: release allocated memory
return EXIT_FAILURE;
}
start_position = strchr(line, '=') + 1;
int time = atoi(start_position);
node->time = time;
}
// read version
if (fgets(line, sizeof line, file) == NULL) {
fprintf(stderr, "Unexpected end of file!\n");
fclose(file);
// TODO: release allocated memory
return EXIT_FAILURE;
}
start_position = strchr(line, '=') + 1;
int version = atoi(start_position);
printf("Version: %d\n", version);
root = sort_songs(root);
SONG * iterator = root;
while (iterator != NULL) {
fprintf(stdout, "\n#EXTINF:%d,%s\n%s", iterator->time, iterator->title, iterator->file);
iterator = iterator->next;
}
fprintf(stdout, "\n");
// free the allocated memory
while (root != NULL) {
SONG * next = root->next;
free(root);
root = next;
}
fclose(file);
return EXIT_SUCCESS;
}
$ gcc -Wall convert_playlist.c
$ ./a.out
Number of entries: 3
Version: 2
#EXTINF:302,Chris Rea - Looking For The Summer
C:\muzika\Chris Rea - Looking For The Summer.mp3
#EXTINF:207,Mambo Kings - Luz de luna
C:\muzika\Mambo Kings - Luz de luna.mp3
#EXTINF:265,Simply Red - Holding Back The Years
C:\muzika\Simply Red - Holding Back The Years.mp3
$
Related
I have a txt file, which contains groups of 3 elements in each line (2 strings for vertices and 1 integer for edge), which i want to use as input to create an adjacency list for a graph.
The txt file is as so: "string1 string2 34" and the elements are separated by tabs.
I've tried for starters trying to read from the file, using fgets , and managed to print the elements, but i'm stuck as to how i can parse them and store them. Any ideas?
A complete solution can be found at https://www.thecrazyprogrammer.com/2017/06/bellman-ford-algorithm-in-c-and-c.html
The Bellman-Ford algorithm in C is also discussed in https://stackoverflow.com/a/36831569/18980756.
Nevertheless, some code based on your input to put the elements into a dynamically allocated linked list:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct FORM {
char *vertice_one;
char *vertice_two;
int weight;
struct FORM *next;
} FORM;
int main() {
int err = 0; // error indicator
// helper to store temporarily store read values
char s1[256], s2[256];
int w;
FORM *firstEntry = NULL; // root element for the list
FILE *file = fopen("forms.txt", "r");
if (file == NULL) goto cleanup;
// read three line elements into variables
while (fscanf(file, "%s%s%d\n", &s1[0], &s2[0], &w) == 3) {
// print read elements for debugging purposes
printf("read: %s-%s-%d\n", s1, s2, w);
// dynamically allocate memory to store the read values
FORM *newEntry = malloc(sizeof *newEntry);
if (newEntry == NULL) {
fprintf(stderr, "Error - Not enough memory!");
err = 1;
goto cleanup;
}
char *vert1 = malloc(strlen(&s1[0]) + 1);
char *vert2 = malloc(strlen(&s2[0]) + 1);
if (vert1 == NULL || vert2 == NULL) {
fprintf(stderr, "Error - Not enough memory!");
err = 1;
goto cleanup;
}
memcpy(vert1, &s1[0], strlen(&s1[0]) + 1);
memcpy(vert2, &s2[0], strlen(&s2[0]) + 1);
newEntry->vertice_one = vert1;
newEntry->vertice_two = vert2;
newEntry->weight = w;
// put new entry to front a linked list
newEntry->next = firstEntry;
firstEntry = newEntry;
}
FORM *p = firstEntry;
while(p != NULL) {
printf("%s\t%s\t%d\n", p->vertice_one, p->vertice_two, p->weight);
p = p->next;
}
FORM *q;
cleanup:
q = firstEntry;
while(q != NULL) {
FORM *entry = q;
q = q->next;
if (entry->vertice_one != NULL) free(entry->vertice_one);
if (entry->vertice_two != NULL) free(entry->vertice_two);
free(entry);
}
if (file != NULL) {
fclose(file);
}
return err;
}
$ gcc -Wall -Wextra graph.c
$ ./a.out
read: vert1-vert2-1
read: vert3-vert4-2
vert3 vert4 2
vert1 vert2 1
$
Now you are in C land and can start thinking about how you want to work with the data read.
I guess
FORM should be named EDGE
vertex_one should be named source
vertex_two should be named destination
weight remains weight
You could avoid the dynamic allocation if you define arrays which are large enough to hold the data from the file.
When compiling my program, I get a LeakSanitizer error where it detected memory leaks at the line word_dict target = (word_dict)malloc(sizeof(dict)) in the newDict function. I don't free target because I return the value for use in other functions below. However, I'm struggling to find when I should call free on the allocated memory. I tried freeing spamDict and nonspamDict in the bayesian_spam_filer function but the memory leak error still persists.
typedef struct dictionary dict;
typedef dict* word_dict;
typedef enum {false, true} bool;
/*
linked list, count is for the total word count and
occur is the numbers of the mails that had the word
*/
struct dictionary{
char word[WORDLENGTH + 1];
int occur;
int count;
word_dict next;
bool updated;
};
// if there is no matching words after searching, create a new node
word_dict newDict(char *string, word_dict next){
word_dict target = (word_dict)malloc(sizeof(dict));
int i = 0;
while(string[i] !='\0' && i<WORDLENGTH) {
target->word[i] = string[i];
i++;
}
target->word[i] = 0;
target->count = 1;
target->next = next;
target->occur = 1;
target->updated = true;
return target;
}
/*
search matching words, if a matching word is found
add 1 to count and return true
no matching word, then return false
*/
word_dict searchDict(char* string, word_dict pos){
word_dict first = pos;
if(strcmp(string, MAILSEPARATOR) == 0) { //end of an email
update(first);
return first;
}
string = preprocess(string);
if(string == NULL) {
return first;
}
int result;
word_dict prevPos=pos;
while(pos != NULL){
if((result = strcmp(pos->word, string)) == 0){
if(!pos->updated) {
pos->occur++;
pos->updated = true;
}
pos->count++;
return first;
} else if(result > 0) { // has passed the position and no matching word, need to add node.
if (prevPos == pos){
return newDict(string,pos);
}
prevPos->next = newDict(string, pos);
return first;
}
prevPos = pos;
pos = pos->next;
}
//printf("null found\n");
prevPos->next = newDict(string, pos);
return first;
}
/*
initialize training
reads the sample mails and creates a linked list of
the percentages of the words occuring in the sample mails
*/
word_dict initializeTraining(char* filename){
FILE *fp = NULL;
fp = fopen(filename, "r");
if(fp == NULL) {
printf("no file found\n");
return NULL;
}
char* string;
string = (char*)malloc(sizeof(char)*50);
word_dict first = NULL;
fscanf(fp, "%s\n", string);
string = preprocess(string);
first = newDict(string, NULL);
while(fscanf(fp,"%s", string) == 1) {
first = searchDict(string, first);
}
fclose(fp);
free(string);
return first;
}
/*
tests whether the mail is pam or not
takes the filename of the test mail,
returns true or false depending on the email's content
*/
bool bayesian_spam_filter(char * filename_for_test_email) {
word_dict spamDict=initializeTraining("spam.txt");
word_dict nonspamDict=initializeTraining("not_spam.txt");
#if DEBUG
printDict(spamDict);
printDict(nonspamDict);
#endif
FILE *stream=NULL;
stream = fopen(filename_for_test_email, "r");
if(stream == NULL){
printf("no file found\n");
return false;
}
char* string;
string = (char*)malloc(sizeof(char)*50);
int ps, pn; // probability of spam mail and non-spam mail
double prob = 0.5;
while(fscanf(stream,"%s", string) == 1){
char* tempString; // for handling the errors happening from string being null during preprocessing
tempString = preprocess(string);
if(tempString == NULL){
continue;
}
if((ps = searchTest(tempString, spamDict)) != 0) {
if((pn = searchTest(tempString, nonspamDict)) != 0) {
printf("ps:%3d, pn:%3d, %s\n", ps, pn, tempString);
prob = prob * (double) ps / ((prob* (double)ps + (1 - prob) * (double) pn));
printf("this probability: %.10f\n", prob);
}
}
}
//printf("%d, %d \n", pSProduct, pNProduct);
//proba=(float)(pSProduct/(pSProduct+pNProduct));
printf("Probability of mail being spam: %.10f\n", prob);
fclose(stream);
free(string);
free(spamDict);
free(nonspamDict);
if (prob > 0.9) {
return true;
}
return false;
}
The reason a leak is reported is that in the end of bayesian_spam_filter you are only freeing the first entry in each linked list associated with spamDict and nonSpamDict so the remainder of each list is leaked:
free(spamDict);
free(nonspamDict);
You need to loop through both of those lists to free all the nodes in the list.
I'm having problems with my C program which works perfectly on Windows but not on Linux. I use the following method for reading line by line a file:
char * getLineOfAnySize(FILE* fp, size_t typicalSize, int *endOfLineDetected,size_t *nrOfCharRead){
char *line; // buffer for our string
int ch; // we will read line character by character
size_t len = 0; // number of characters read (character counter)
size_t lineSize = typicalSize; // initial size of the buffer allocated for the line
*nrOfCharRead = 0;
if(!fp) return NULL; // protection
// allocating the buffer
line = realloc(NULL, sizeof(char)*lineSize); // expected size of the line is pathHead to typicalSize
if (!line) return line; // protection, if we fail to allocate the memory we will return NULL
while (1) { // loop forever
ch = fgetc(fp); // getting character by character from file
if (ch == '\n') break; // end of line detected - breaking the loop
if( ch == EOF) {
*endOfLineDetected = 1;
break; // end of file detected - breaking the loop
}
line[len++] = ch; // store the character in the line buffer, increase character counter
if (len == lineSize){ // we reached the end of line buffer (no more room)
lineSize = lineSize + 64; // we have to increase the line size
line = realloc(line, sizeof(char)*(lineSize)); // line buffer has new size now
if (!line) return line; // if we fail to allocate memory we will return NULL
}
if( (len == 0) && *endOfLineDetected){ // empty file
*endOfLineDetected = 1;
break;
}
}
line[len++] ='\0'; // ending the string (notice there is no '\n' in the string)
*nrOfCharRead = len;
return line; // return the string
}
The workflow of my program is the following: I gave in input a path, the file correspondent to the path contains in each line others file path that I read with the function above and put into a structure. On each i apply the KMP algorithm to get the occurrences of a string.
The problem comes in my program when I try to open the files that correspond to the paths I saved earlier:
FILE *fp = NULL;
fp = fopen(list->path, "r");
if(fp == NULL){
fprintf(stderr, "Cannot open %s, exiting. . .\n", list->path);
exit(1);
}
On the screen is displayed:
, exiting ...
This is so weird because of file opening problem the output should be:
Cannot open "list->path content", exiting. . .
Even though I don't know why it gives me this error while opening the path read from the input file. During compiling there's no problem. I was thinking about buffer problems derived by the function "getLineOfAnySize. I'm not a Linux user, I was just trying to run the program in order to make sure it will run on both OS. Don't think about design issues or logical issues because on Windows everything works perfectly. Big up to everyone who will help me! Please ask further information about the code if needed.
EDIT:
The content of the input file is:
/home/xxx/Scrivania/find/try
/home/xxx/Scrivania/find/try1
Note that find is the directory of the project.
The following is a sample of my program in order to make more sense of variable and construct:
foo.c :
#include "foo.h"
FILE *fInput = NULL;
FILE *fp = NULL;
char *line1;
char *line2;
int endOfLineDetected = 0;
size_t nrOfCharRead = 0;
char ch;
fWord *w = NULL;
fWord *wordHead = NULL;
fWord *wordTail = NULL;
fList *list = NULL;
fList *listHead = NULL;
fList *listTail = NULL;
fPath *pathHead = NULL;
fPath *pathTail = NULL;
fPosition *positionHead = NULL;
fPosition *head = NULL;
fPosition *current = NULL;
char * getLineOfAnySize(FILE* fp, size_t typicalSize, int *endOfLineDetected,size_t *nrOfCharRead);
int main(int argc, char *argv[]){
fInput = fopen(argv[1], "r"); //the file that contains the path of the file in which search.
if(fInput == NULL){
fprintf(stderr, "Cannot open %s, exiting. . .\n", argv[1]);
exit(1);
}
while(!endOfLineDetected){ //read line by line the input file in order to save the path in a structure
line1 = getLineOfAnySize(fInput,128,&endOfLineDetected,&nrOfCharRead);
fList *node = malloc (sizeof(fList));
node->path = line1;
node->next = NULL;
if(listHead == NULL){
listHead = listTail = node;
}else{
listTail = listTail->next = node;
}
}
list = listHead;
fclose(fInput);
do{
fWord *app = malloc(sizeof(fWord));
printf("Insert the word to search: ");
scanf("%s", app->word);
app->totalOccurences = 0;
app->p = NULL;
app->next = NULL;
if(wordHead == NULL){
wordTail = wordHead = app;
}else{
wordTail = wordTail->next = app;
}
printf("Do you want to insert another word? (Y/N): ");
scanf(" %c", &ch);
}while(ch == 'y' || ch == 'Y');
w = wordHead;
while(w != NULL){
while(list != NULL){
w->p = malloc(sizeof(fPath));
w->p->fileOccurrences = 0;
w->p->path = list->path;
w->p->position = NULL;
w->p->next = NULL;
if(pathHead == NULL){
pathTail = pathHead = w->p;
}else{
pathTail = pathTail->next = w->p;
}
fp = fopen(w->p->path, "r");
if(fp == NULL){
fprintf(stderr, "Cannot open %s, exiting. . .\n", w->p->path);
exit(1);
}
int countLine = 0;
endOfLineDetected = 0;
while(!endOfLineDetected){
line2 = getLineOfAnySize(fp,128,&endOfLineDetected,&nrOfCharRead);
int n = strlen(line2);
int m = strlen(w->word);
w->p->fileOccurrences = w->p->fileOccurrences + KMP(line2, w->word, n, m, countLine, w->p);
countLine = countLine + 1;
}
w->totalOccurences = w->totalOccurences + w->p->fileOccurrences;
w->p->position = getHead();
w->p = w->p->next;
list = list->next;
fclose(fp);
}
w->p = pathHead;
list = listHead;
w = w->next;
pathHead = NULL;
}
w = wordHead;
while(w != NULL){
printf("WORD %s \r\n", w->word);
printf("TOTAL %d \r\n", w->totalOccurences);
pathHead = w->p;
while(w->p != NULL){
printf("FILE %s \r\n", w->p->path);
printf("OCCURENCES %d \r\n", w->p->fileOccurrences);
positionHead = w->p->position;
while (w->p->position != NULL){
printf("%d %d\r\n", w->p->position->line, w->p->position->character);
w->p->position = w->p->position->next;
}
w->p->position = positionHead;
w->p = w->p->next;
}
w->p = pathHead;
w = w->next;
}
w = wordHead;
printf("\r\n");
freeMemory();
freeKMP();
return 0;
}
char * getLineOfAnySize(FILE* fp, size_t typicalSize, int
*endOfLineDetected,size_t *nrOfCharRead){
char *line; // buffer for our string
int ch; // we will read line character by character
size_t len = 0; // number of characters read (character counter)
size_t lineSize = typicalSize; // initial size of the buffer allocated for the line
*nrOfCharRead = 0;
if(!fp) return NULL; // protection
// allocating the buffer
line = realloc(NULL, sizeof(char)*lineSize); // expected size of the line is pathHead to typicalSize
if (!line) return line; // protection, if we fail to allocate the memory we will return NULL
while (1) { // loop forever
ch = fgetc(fp); // getting character by character from file
if (ch == '\n') break; // end of line detected - breaking the loop
if( ch == EOF) {
*endOfLineDetected = 1;
break; // end of file detected - breaking the loop
}
line[len++] = ch; // store the character in the line buffer, increase character counter
if (len == lineSize){ // we reached the end of line buffer (no more room)
lineSize = lineSize + 64; // we have to increase the line size
line = realloc(line, sizeof(char)*(lineSize)); // line buffer has new size now
if (!line) return line; // if we fail to allocate memory we will return NULL
}
if( (len == 0) && *endOfLineDetected){ // empty file
*endOfLineDetected = 1;
break;
}
}
line[len++] ='\0'; // ending the string (notice there is no '\n' in the string)
*nrOfCharRead = len;
return line; // return the string
}
// Function to implement KMP algorithm
int KMP(const char* X, const char* Y, int m, int n, int line, fPath *app){
int count = 0;
// next[i] stores the index of next best partial match
int next[n + 1];
for (int i = 0; i < n + 1; i++)
next[i] = 0;
for (int i = 1; i < n; i++){
int j = next[i + 1];
while (j > 0 && Y[j] != Y[i])
j = next[j];
if (j > 0 || Y[j] == Y[i])
next[i + 1] = j + 1;
}
for (int i = 0, j = 0; i < m; i++){
if(X[i] == Y[j]){
if (++j == n){
count = count + 1; //conta le occorrenze della parola nella riga in input
fPosition *node = malloc (sizeof(fPosition));
node->line = line;
node->character = i - j + 1;
node->next = NULL;
if(head == NULL){
current = head = node;
}else{
current = current->next = node;
}
app->position = current;
}
}
else if (j > 0) {
j = next[j];
i--; // since i will be incremented in next iteration
}
}
return count;
}
fPosition * getHead(){ //rimette il puntatore alla testa della lista
fPosition *app = head;
head = NULL;
return app;
}
void freeKMP(){
free(head);
free(current);
}
void freeMemory(){
list = listHead;
fList *tempL = NULL;
while(list != NULL){
tempL = list;
list = list->next;
free(tempL);
}
w = wordHead;
fWord *tempW = NULL;
fPath *tempP = NULL;
fPosition *tempO = NULL;
while(w != NULL){
while(w->p != NULL){
while(w->p->position != NULL){
tempO = w->p->position;
w->p->position = w->p->position->next;
free(tempO);
}
tempP = w->p;
w->p = w->p->next;
free(tempP);
}
tempW = w;
w = w->next;
free(tempW);
}
free(w);
free(line1);
free(line2);
free(wordHead);
free(wordTail);
free(listHead);
free(listTail);
free(pathHead);
free(pathTail);
free(positionHead);
}
foo.h:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct fileList{
char *path;
struct fileList *next;
};
struct filePath{
char *path;
int fileOccurrences;
struct OccurrencesPosition *position;
struct filePath *next;
};
struct fileWord{
char word[50];
int totalOccurences;
struct filePath *p;
struct fileWord *next;
};
struct OccurrencesPosition{
int line;
int character;
struct OccurrencesPosition *next;
};
typedef struct filePath fPath;
typedef struct fileWord fWord;
typedef struct OccurrencesPosition fPosition;
typedef struct fileList fList;
fPosition * getHead();
int KMP(const char* X, const char* Y, int m, int n, int line, fPath *app);
void freeMemory();
void freeKMP();
Maybe also the way I free memory isn't correct.
This is not a full answer, but a hint for further analysis.
I tested the program with the input file contents as shown in the question and entered one or two words.
If the first file does not exist, I get an error message as expected:
Cannot open /home/yuripaoloni/Scrivania/find/try, exiting. . .
Then I modified the input file to list two files that exist on my system and get an error message
Cannot open , exiting. . .
I extended the code that tries to open the file to get more output:
fp = fopen(w->p->path, "r");
if(fp == NULL){
fprintf(stderr, "Cannot open %s, exiting. . .\n", w->p->path);
perror("fopen");
exit(1);
} else {
printf("Successfully opened %s\n", w->p->path);
}
This prints
$ ./foo input
Insert the word to search: foo
Do you want to insert another word? (Y/N): y
Insert the word to search: bar
Do you want to insert another word? (Y/N): y
Insert the word to search: baz
Do you want to insert another word? (Y/N): n
Successfully opened /home/username/tmp/try
Successfully opened /home/username/tmp/try1
Cannot open , exiting. . .
fopen: No such file or directory
Apparently your program tries to open a third file after the existing file names. w->p->path might be a NULL pointer or may point to an empty string.
The same error occurs when I enter only one word. I did not further analyze the error.
To find out why your program tries to open a file with an empty name, you can run it in a debugger or add more output to see how many loop cycles are executed when processing the lists and which data you find.
I was wondering if you could help me out I'm really stuck on this code I wrote. I'm supposed to pre-order fill a tree from a file that is structured in the following way.
Hello
goodbye
yes
' ' <- This is an actual space in the file
no
end of file
When ever there is a space I wanna return back to the node previous and go right and return whenever it reaches EOF.
So the text above would be structured in the following way
hello
goodbye null no right child
yes no
This function is supposed to fill my tree in preorder. I'm grabbing the data using my readFile function here
char *readFile(FILE *fp)
{
int c = 0;
int i = 0;
size_t capacity = 10;
char *arr = NULL;
char* temp = NULL;
arr = (char*) malloc(capacity * sizeof(char));
while (((c = fgetc(fp)) != '\n') && (c != EOF))
{
if(capacity == (i+2))
{
capacity *= 2 ;
temp = (char*)realloc(arr,capacity * sizeof(char));
/*Assigns Address to newly allocated array*/
arr = temp;
}
arr[i] = c;
i++;
}
arr[i-1] = '\0';
if(arr[0] == '\r') /* Line spaces to move up*/
{
printf("Got here SPACE\n");
arr[0] = ' ';
}
else if(c == EOF)/*if its an end of file return*/
{
printf("Got here EOF \n");
arr[0] = ' ';
}
return arr;
}
My recursive algorithm to fill the tree is called populate. I'm not really that great at recursion but I've walked though my code multiple times and can't see what's obviously wrong. Currently it seems I can only print the root. Trying to read the left or right root data gives me an immediate seg fault
void populate(FILE *fp,struct node *root)
{
char *data = readFile(fp);
if(data[0] == ' ') /*possible issues with usingn null charater? */ /*statement is true for both EOF and spaces*/
{
return;
}
printf("Creating Node\n");
if(root == NULL)
{
root = createNode();/* create the current root */
root->data = data;/*assign data*/
}
printf("%s\n",data);
populate(fp,root->left);
populate(fp,root->right);
}
my main
int main(int argc, char *argv[])
{
FILE *fp;
node *root = createNode();
fp = fopen("qa.db","r+");
if(fp == NULL)
{
printf("File not open");
}
populate(fp,root);
if(root == NULL){
printf("Equal to NULL\n");
}
printTree(root);
/*check = checkFile(fp)*/
fclose(fp);
return 0;
I'm trying to make a program that would read a linked list and output all of the info that it has read. My problem is that I can't simply output. There is some problem that I can't find.
#include <stdio.h>
#include <stdlib.h>
struct sarasas
{
char *reiksme;
struct sarasas *kitas;
};
int main()
{
struct sarasas *sarasasPtr, *pradz, *pab, *elem;
pradz = NULL;
pab = NULL;
FILE *duomPtr;
printf("Iveskite duomenu failo pavadinima: ");
char failas[255];
scanf("%s", failas);
duomPtr = fopen(failas, "r");
if(duomPtr == NULL)
{
printf("Toks duomenu failas neegzistuoja \n");
exit(0);
}
int k = 0;
char paimtaReiksme[255];
while(fscanf(duomPtr, "%s", paimtaReiksme) != EOF)
{
if(k == 0)
{
sarasasPtr = (struct sarasas*)malloc (sizeof (struct sarasas));
sarasasPtr->reiksme = paimtaReiksme;
sarasasPtr->kitas = NULL;
pradz = sarasasPtr;
pab = sarasasPtr;
}
else
{
sarasasPtr = (struct sarasas*)malloc (sizeof (struct sarasas));
sarasasPtr->reiksme = paimtaReiksme;
sarasasPtr->kitas = NULL;
pab->kitas = sarasasPtr;
pab = sarasasPtr;
}
k++;
}
if(pradz == NULL && pab == NULL)
{
printf("Tuscia\n");
exit(0);
}
FILE *rptr;
printf("Iveskite rezultatu failo pavadinima: ");
char failas2[255];
scanf("%s", failas2);
rptr = fopen(failas2, "w");
while(sarasasPtr->kitas != NULL)
{
fprintf(rptr, "%s", sarasasPtr->reiksme);
}
return 0;
}
You have an infinite loop in your code.
while(sarasasPtr->kitas != NULL)
{
fprintf(rptr, "%s", sarasasPtr->reiksme);
}
Here in the above while loop, you are trying to print the same element over and over again and thus you end up in an infinite loop.instead, you must change the pointer to next element after each and every iteration. You can try something like this:
while(sarasasPtr != NULL) //check whether pointer points to NULL
{
fprintf(rptr, "%s", sarasasPtr->reiksme);
sarasasPtr = sarasasPtr->kitas; //make pointer point to next element
}
additionally, you need not cast the the return value of malloc : Here's why(click)