Strtok for every line and search a word in c - c

I open the input file
I read it
Store an 2D array
split into tokens
firslt strtok for "\n" and store it
secondly strtok for ":" ignore it
and then strtok for "," and store it
I want to search a word for every single line (which I stored it step 5)
For searching I use strstr but I can't do it.
I add my input file and code .
int
main ()
{
FILE *fp;
fp = fopen ("C:\\input.txt", "r");
char *name[10][10];
char row[100];
char *token, *tkn, *tk;
int h = 0, f = 0, l = 0;
for (h = 0; h < 9; h++)
{
for (f = 0; f < 9; f++)
name[h][f] = NULL;
}
while (fgets (row, sizeof (row), fp))
{
token = strtok (row, "\n");
name[l][0] = strdup (token);
//printf("%s",name[l][0]);
tkn = strtok (token, ":");
tk = strtok (tkn, ",");
isim[l][1] = strdup (tk);
if (strstr (name[l][1], name[l + 1][0]) == 0
|| strstr (name[l][1], name[l + 2][0]) == 0
|| strstr (name[l][1], name[l + 3][0]) == 0)
{
}
l++;
}
fclose (fp);
}
I want to insert a linked list wth this function.
struct AdjListNode{
char *courseName;
char *studentName;
struct AdjList *head;
struct AdjListNode *nextPtr;};
typedef struct AdjListNode node;
typedef struct AdjListNode* nodePtr;
typedef struct AdjListNode** nodePtrPtr;
nodePtr insertVertex(nodePtrPtr header,char *studentName,char *courseName){
nodePtr newNode, temp, prev;
// create node to insert and assign values to its fields
//newNode=createAdjListNode(studentName,courseName);
newNode=malloc(sizeof(node));
newNode->studentName=studentName;
newNode->courseName=courseName;
newNode->nextPtr=NULL;
// if LL empty
if (*header == NULL)
*header=newNode;
// if LL not empty
else {
temp=*header;
while (temp != NULL && (strcmp(temp->courseName,newNode->courseName)<0)) {
prev=temp;
temp=temp->nextPtr;
}
while (temp!=NULL && (strcmp(temp->courseName,newNode->courseName)==0)) {
printf("\n existent key \n");
return temp;
}
// insert node in a sorted fashion
if (temp!=NULL)
newNode->nextPtr=temp;
// if value to insert is the least in LL then have header point to node
if (temp==*header)
*header=newNode;
// otherwise insert node in correct position
else
prev->nextPtr=newNode;
}
return newNode;}
My input.txt file:
George :Math1,History2,Math2
ELizabeth :Math2,Germany1,spanish1
Adam :Germany1,History2,Math1
I want to create a graph with lecture names and I want to use adjancecy list. For adjancecy list I need the connection of two lectures but I'm stuck with this step. How can I search whole line and then store an array. For example I search Math1 . it is in 2 lines .And then I want to create an adj list Math1 ->History2->Math2->Germany1 for Math1 .Please help me

Related

Problem with pointers to three different linked list

I'm having problem with pointers in a C program that count the occurrences of a string or more in a bunch of file. The program take in input a file which contains the paths of the files in which search the occurrences. All the files that i will mention are contained in the same folder of the project, whose name is "find". In my case, the input file is "path.txt":
C:\Users\Utente\Desktop\find\try.txt
C:\Users\Utente\Desktop\find\try1.txt
The try.txt content is:
abc
abc
abc
ac
ac
ac
ac
The try1.txt content is:
ac
ac
ac
ac
abc
abc
abc
My program is composed by 4 files, two header-files and two source files:
find.c:
#include "find.h"
int main(int argc, char * argv[]){
FILE *fInput = NULL;
FILE *fp = NULL;
char *line1;
char *line2;
int endOfLineDetected = 0;
size_t nrOfCharRead = 0;
char ch;
fWord *w = NULL;
fWord *start = NULL;
fWord *tail = NULL;
fPath *head = NULL;
fPath *current = NULL;
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);
fPath *node = malloc (sizeof(fPath));
node->path = line1;
node->fileOccurrences = 0;
node->position = NULL;
node->next = NULL;
if(head == NULL){
current = head = node;
}else{
current = current->next = node;
}
}
fclose(fInput);
//create a linked list of the type fWord, one structure for each word.
do{
fWord *app = malloc(sizeof(fWord));
printf("Insert the word to search: ");
scanf("%s", app->word);
app->totalOccurences = 0;
app->p = head;
app->next = NULL;
if(start == NULL){
tail = start = app;
}else{
tail = tail->next = app;
}
printf("Do you want to insert another word? (Y/N): ");
scanf(" %c", &ch);
}while(ch == 'y' || ch == 'Y');
w = start; //pointer back to the top of the fWord structure
//traverse all the structure and execute the algorithm
while(w != NULL){
while(w->p != NULL){
fp = fopen(w->p->path, "r");
if(fp == NULL){
fprintf(stderr, "Cannot open %s, exiting. . .\n", w->p->path);
exit(1);
}
int countLine = 0;
w->p->fileOccurrences = 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(); // //pointer back to the top of the fPosition structure
w->p = w->p->next;
fclose(fp);
}
w->p = head; //pointer back to the top of the fPath structure
}
w = start; //pointer back to the top of the fWord structure
//traverse all the structure and print out the occurrences and their position
while(w != NULL){
w->p = head;
printf("WORD %s \r\n", w->word);
printf("TOTAL %d \r\n", w->totalOccurences);
while(w->p != NULL){
printf("FILE %s \r\n", w->p->path);
printf("OCCURENCES %d \r\n", w->p->fileOccurrences);
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 = w->p->next;
}
w = w->next;
}
printf("\r\n"); //the file ends with an empty line
return 0;
}
//method used for read 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 up 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
}
find.h:
#include "kmp.h"
char * getLineOfAnySize(FILE* fp, size_t typicalSize, int *endOfLineDetected,size_t *nrOfCharRead);
kmp.c:
#include "kmp.h"
fPosition *head = NULL;
fPosition *current = NULL;
// 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; //count the occurrences of the string in this file
fPosition *node = malloc (sizeof(fPosition));
node->line = line; //the current line
node->character = i - j + 1; //the shift in which occurs
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; //return the number of occurences found
}
//take the pointer back to the top of fPosition
fPosition * getHead(){
fPosition *app = head;
head = NULL;
return app;
}
kmp.h:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct filePath{
char *path; //the file path
struct filePath *next;
};
struct OccurrencesPosition{
int line; //line in which an occurrence is founded
int character; //shift at which the occurrences comes
struct filePath pathInfo;
struct OccurrencesPosition *next; //pointer to the next occurrences
};
struct fileWord{
char word[50]; //the string to search
int totalOccurences; //the total occurrences of the string
int fileOccurrences; //the occurrences of each file
struct OccurrencesPosition *position; //pointer to the linked list which tracks all the occurrences and their positions
struct fileWord *next; //pointer to the next word
};
typedef struct filePath fPath;
typedef struct fileWord fWord;
typedef struct OccurrencesPosition fPosition;
fPosition * getHead();
int KMP(const char* X, const char* Y, int m, int n, int line, fPath *app);
The problem is that when i run my program passing in input "abc" and "ac" it returns wrong value. More precisely, returns the value corresponding to "ac" in both cases. Here's the execution:
PS C:\Users\Utente\Desktop\find> gcc find.c kmp.c -o "find.exe"
PS C:\Users\Utente\Desktop\find> .\find.exe "path.txt"
Insert the word to search: abc
Do you want to insert another word? (Y/N): Y
Insert the word to search: ac
Do you want to insert another word? (Y/N): N
WORD abc
TOTAL 6
FILE C:\Users\Utente\Desktop\find\try.txt
OCCURENCES 4
3 0
4 0
5 0
6 0
FILE C:\Users\Utente\Desktop\find\try1.txt
OCCURENCES 4
0 0
1 0
2 0
3 0
WORD ac
TOTAL 8
FILE C:\Users\Utente\Desktop\find\try.txt
OCCURENCES 4
FILE C:\Users\Utente\Desktop\find\try1.txt
OCCURENCES 4
As you can see, the WORD and TOTAL are correct in both cases, but the occurrences not. They correspond to "ac" in both cases.
The correct output should be:
WORD abc
TOTAL 6
FILE C:\Users\Utente\Desktop\find\try.txt
OCCURENCES 3
0 0
0 1
0 2
FILE C:\Users\Utente\Desktop\find\try1.txt
OCCURENCES 3
4 0
5 0
6 0
WORD ac
TOTAL 8
FILE C:\Users\Utente\Desktop\find\try.txt
OCCURENCES 4
3 0
4 0
5 0
6 0
FILE C:\Users\Utente\Desktop\find\try1.txt
OCCURENCES 4
0 0
1 0
2 0
3 0
I think that the problem is with the fPosition pointers. Thanks to anyone who helps.
You have design issue.
The problem is occurrences info you are maintaining as part of filePath list.
struct filePath{
char *path; //the file path
int fileOccurrences; //the occurrences of each file
struct OccurrencesPosition *position; // here *****************
struct filePath *next;
};
And file path info you are maintaining as part of fileWord list.
struct fileWord{
char word[50]; //the string to search
int totalOccurences; //the total occurrences of the string
struct filePath *p; //pointer to the linked list of all the files
struct fileWord *next; //pointer to the next word
};
Since you only have one file path list, each word in fileWord list is actually pointing to same filepath list.
Every word is pointing to same file path list
fWord *app = malloc(sizeof(fWord));
printf("Insert the word to search: ");
scanf("%s", app->word);
app->p = head; //here
and you are updating the position info inside the filepath for every word.
w->p->position = getHead(); // //pointer back to the top of the fPosition structure
Thus filePath list is holding position info only for the latest word you search.
Update:
Your design should look as below.
struct filePath{
char *path; //the file path
struct filePath *next;
};
struct OccurrencesPosition{
int line; //line in which an occurrences is founded
int character; //shift at which the occurrences comes
struct filePath pathInfo;
struct OccurrencesPosition *next; //pointer to the next occurrences
};
struct fileWord{
char word[50]; //the string to search
int totalOccurences; //the total occurrences of the string
int fileOccurrences; //the occurrences of each file
struct OccurrencesPosition *position; //pointer to the linked list which tracks all the occurrences and their positions
struct fileWord *next; //pointer to the next word
};

C language i m having trouble doing Binary search function and passing array to function?

C program for binary search
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node { //LINKED LIST FUNCTION
char *words;
struct node *next;
} Node;
//reads single words from file also allocate needed space.
char *strdup (const char *s) {
char *d = malloc (strlen (s));
if (d == NULL) return NULL;
strcpy (d,s);
return d;
}
int main (int argc, char *argv[])
{
FILE *file1;
FILE *file2;
FILE *file3;
file1 = fopen (argv[1],"r");
file2 = fopen (argv[2],"r");
char letters [100];
char tempLetters [100][50];
//I tempLetters FOR BINARY SEARCH it has Words stored in it
Node *current , *head;
int check;
head = current = NULL;
int i = 0;
while (! feof (file1)){
fscanf (file1,"%s",letters);
Node * list = malloc (sizeof (Node));
list -> words = strdup(letters);
list -> next = NULL;
if(head == NULL){
current = head = list;
} else {
current = current->next = list;
}
// printf ("%s\n", current->words);
strcpy (tempLetters[i],current -> words);
//HERE I STORED Words in tempLetters
i++;
//i++ is for Keeping track of how many words.
}
// FILE 2 reading queries:
char query [100]; //Just a local variable
int q = 0;
char QArray [100][50];//NEED THIS ONE FROM BINARY SEARCH
while (!feof (file2)){
fscanf (file2, "%s", query);
if (!feof (file2)){
//Keeping track of how many words
strcpy (QArray[q], query);
q++;
}
}
} /* //Binary Search
I want to read single words from QArray and find that if there is
a same word in temLetters array. and If there is then print that word
and also print its ARRAY index. If there is not then read next
word from QArray till QArray == NULL.
I AM HAVING TROUBLE PASSING THOSE TOO ARRAYS in function.
*/
fclose (file1);
fclose (file2);
return 0;}
char *d = malloc (strlen (s)); is wrong. You need char *d = malloc (strlen (s) + 1);. That needs to be fixed first. It may or may not resolve other errors. – R Sahu

fscanf to a linked list

I'm in trouble with my code again.
I want to fscanf result.txt to structures with linked list, but it don't work;
I think the simply linked list must be enought;
The problem is: the program just write the first line, but nothing else.
result.txt format:
point name (for examples)
623 john
457 peter
312 chuck
etc.
The code:
#include <stdio.h>
#include <stdlib.h>
typedef struct ranklist {
int point;
char* name;
struct ranklist *next;
} ranklist;
int how_many_records(FILE *fp){
char ch;
int line=0;
int status;
rewind(fp);
while((status=fscanf(fp, "%*d %*[^\n]%c", &ch))==1)
++line;
if(status != EOF){
++line;
}
rewind(fp);
return line;
}
int how_many_letter(FILE *fp){
int letter = 0;
long pos = ftell(fp);
//fscanf(fp, " %*[^\n]%n", &letter);
fscanf(fp, " %*s%n", &letter);
fseek(fp, pos, SEEK_SET);
return letter;
}
int main(void){
FILE *fp = fopen("result.txt","r");
int name_length;
int lines = how_many_records(fp);
ranklist *r = malloc(lines * sizeof(*r));
ranklist *first = r;
for ( r=first ;r != NULL; r = r->next){
fscanf(fp, "%d", &(r->point));
name_length = how_many_letter(fp);
r->name = malloc(name_length + 1);
fscanf(fp,"%s", r->name);
}
fclose(fp);
for ( r=first ;r != NULL; r = r->next){
printf("%d %s\n", r->point, r->name);
}
free(r);
return 0;
}
fscanf(fp, "%d", &r[y].point);
Here, y is uninitialized.
You need to put y = 0, or, IMO, better to use &(r->point) [and the same goes for r[y].name also]
Suggestion: for reading and parsing whole lines better to use fgets()
You have multiple problems with the creation of the list.
Lets start with the loop:
for ( r=first ;r != NULL; r = r->next){
Nowhere in the loop do you initialize r->next, so after the first iteration you will make y point to totally random memory, leading to undefined behavior.
As mentioned in another answer you don't initialize the variable y, which is another cause of undefined behavior.
You also change r, so r will not point to the original memory you allocated so doing r[y] is a third cause of undefined behavior.
And after the loop you call free with the modified pointer y, which will also lead to undefined behavior. And you don't free the names you allocate in the loop, so have multiple memory leaks as well.
There is no need to pre-allocate the nodes at all, just allocate when needed.
Something like
ranklist *head = NULL;
FILE *fp = fopen(...);
// Read the file and create the list
char buffer[256];
while (fgets(buffer, sizeof(buffer), fp) != NULL)
{
ranklist *node = malloc(sizeof(ranklist));
node->name = malloc(strlen(buffer)); // Will allocate a little more than needed
sscanf(buffer, "%d %s", &node->point, node->name);
node->next = head;
head = node;
}
// Print the list
for (ranklist *n = head; n != NULL; n = n->next)
{
printf("%d %s\n", n->point, n->name);
}
// Free the list
while (head != NULL)
{
// Unlink the first node in the list
ranklist *n = head;
head = n->next;
// And free it
free(n->name);
free(n);
}
The code above doesn't have any error checking, it also have some overhead when allocating space for the name, but it will be safe, it will not handle unrealistically long names, and the list will actually be a stack (last item read will be first in the list).
Function to get the length of the name from the buffer read with fgets:
size_t get_name_length(char *buffer)
{
// Since the buffer was read with `fgets` we need to get rid
// of the newline at the end, if it's there
size_t length = strlen(buffer);
if (buffer[length - 1] == '\n')
buffer[length - 1] = '\0'; // "Remove" by terminating the string
// Find the space dividing the point and the name
char *space = strchr(buffer, ' ');
// Just in case there are multiple whitespace characters in the string
while (*space != '\0' && isspace(*space))
++space;
// Now `space` points to the first non-space letter in the name
// (or to the string terminator, if there's no name
// Then length of the name is the remainder of the string
return strlen(space);
}
FILE *fp = fopen("result.txt","r");
int name_length;
//Just create a link if you use as an array
//int lines = how_many_records(fp);
//ranklist *r = malloc(lines * sizeof(*r));
ranklist *first=NULL, *curr, *r;
int point;
while(1==fscanf(fp, "%d", &point)){
r = malloc(sizeof(*r));//allocate one record
r->next = NULL;
r->point = point;
name_length = how_many_letter(fp);
r->name = malloc(name_length + 1);
fscanf(fp, "%s", r->name);
//make link
if(first == NULL)
first = curr = r;
else
curr = curr->next = r;
}
fclose(fp);
for (r = first; r != NULL; r = r->next){
printf("%d %s\n", r->point, r->name);
}
for (r = first; r != NULL; ){
ranklist *tmp = r->next;//Save next for free(r)
free(r->name);
free(r);
r = tmp;
}
//output the list
void print(ranklist *first){
while(first != NULL){
printf("%d %s\n", first->point, first->name);
first = first->next;
}
}

How to get word before and after the current word in a file?

I have a file, "data.txt" that consists of the following: http://pastebin.com/FY9ZTQX6
I'm trying to get the word before and after the "<". The old word being the one on the left and the new word being the one on the right. This is what I have so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/*
Name: Marcus Lorenzana
Assignment: Final
*/
//binary tree struct to hold left and right node
//as well as the word and number of occurrences
typedef struct node
{
char *word;
int count;
struct node *left;
struct node *right;
}
node;
//,.?!:;-
int punctuation[7];
void insert(node ** dictionary, node * entry);
char* readFile(char* filename);
void printDictionary(node * tree);
void toLower(char** word);
void getReplacementWords(char *filecontents, char **newWord, char **oldWord) ;
int main()
{
char *word;
char* filecontents = readFile("data.txt");
char* oldWord;
char* newWord;
//create dictionary node
node *dictionary;
node *entry;
//read words and punctuation in from the text file
word = strtok (filecontents, " \n");
dictionary = NULL;
while (word != NULL)
{
//word = strlwr(word);
entry = (node *) malloc(sizeof(node));
entry->left = entry->right = NULL;
entry->word = malloc(sizeof(char)*(strlen(word)+1));
entry->word = word;
insert(&dictionary,entry);
word = strtok (NULL, " \n");
}
//printDictionary(dictionary);
filecontents = readFile("data.txt");
getReplacementWords(filecontents,&newWord,&oldWord);
return 0;
}
void insert(node ** dictionary, node * entry)
{
if(!(*dictionary))
{
*dictionary = entry;
entry->count=1;
return;
}
int result = strcmp(entry->word,(*dictionary)->word);
if(result<0){
insert(&(*dictionary)->left, entry);
entry->count++;
}
else if(result>0){
insert(&(*dictionary)->right, entry);
entry->count++;
} else {
entry->count++;
}
}
//put file contents in string for strtok
char* readFile(char* filename)
{
FILE* file = fopen(filename,"r");
if(file == NULL)
{
return NULL;
}
fseek(file, 0, SEEK_END);
long int size = ftell(file);
rewind(file);
char* content = calloc(size + 1, 1);
fread(content,1,size,file);
return content;
}
void printDictionary(node * dictionary)
{
if(dictionary->left) {
printDictionary(dictionary->left);
}
printf("%s\n",dictionary->word);
if(dictionary->right) {
printDictionary(dictionary->right);
}
}
void getReplacementWords(char *filecontents, char **newWord, char **oldWord) {
char *word;
word = strtok (filecontents, " \n");
while (word != NULL)
{
printf("\n%s",word);
int result = strcmp(word,"<");
if (result == 0) {
printf("\nFound replacement identifier");
}
word = strtok (NULL, " \n");
}
}
you can use
fscanf(filename , "%s < %s" , firstStringContainer , secondStringContainer)
after using fseek to get to the line containing the < character this will get the string before the < to be stored in firstStringContainer and the one after in secondStringContainer
here's a code a recommand you to use :
int found = 0;
char buffer[chooseYourSize];
char firstStringContainer[chooseYourSize] , secondStringContainer[chooseYourSize];
while(fgets(buffer , sizeof(buffer) , filename) != NULL)
{
if(strchr(buffer , '<'))
{
found++;
break;
}
}
if(found)
{
fscanf(file , "%s < %s" , firstStringContainer , secondStringContainer);
}
of course this only works if the lines targeted only contains the three elements string < string which is the case here
If your data is in the format of STRING1 < STRING2 you can do:
fscanf(file,"%s < %s", string1, string2);
if it's somewhere on a line it's going to be a little more difficult. What you can do is grab lines from the file and put them into a buffer, then locate the >, go back to the beginning of the first string, and read what you want.
while(fgets(buff,sizeof(buff),file) != NULL
{
if( (pointer = strstr(buff," > ")) != NULL)
{
//now you have located the > just go back
//in the buff till you reach the start of
//string1 and then use
sscanf(buff+(pointer * sizeof(char)),"%s > %s",string1, string2)
}
}
it's been a while since I did this so there might be syntax errors
You can use fseek() in a loop to skip 1 element forward/back and verify if it is space or > or other needed character (another function from string.h).
When you find this symbol, you can move the pointer forward/back to another space or other needed character, remember the number of skipped characters N and then copy N symbols to a string variable.
substitute < replacement
^ find this symbol
substitute < replacement
^ make a loop that makes `counter++` when it finds `space`
(int counter = 0;)
substitute < replacement
^ the loop will continue and will find the 2nd `space`, and make `counter++`
when `counter == 2` (1 space after and 1 before the word) the loop stops.
Now `file` pointer points to the `space` symbol before the 1st word.
Then skip 1 element forward (using `fseek()`) and now you have
`file` pointer that points to the 1st word.
And now you can do whatever you want!
Do the same actions to find the 2nd word (file pointer will point to the 2nd word so you will be able to call this function again: it will be looking for thw 2nd > in your text) and make a function findWordsNearArrow() or something like that.
You can call this function in a loop so when it finds EOF it will return specific value that you can use to exit the loop.
Think again. (c)
Use fgets() and strchr() to get to the line with the <.
while (strchr (fgets (buffer, sizeof (buffer), file), '<') == NULL)
; // do nothing
Then use strtok() to parse the current line in the buffer
strcpy (oldword, strtok (buffer, "<"));
strcpy (newword, strtok (NULL, "\n"));

C Hash Table Problem, Everything has same value

For some reason when I insert elements into my hash table all elements at the same index end up having the same value. For example if I have three elements at index 2 of the hash table then all three would have the same "word" as the last one inserted into that index. I dynamically allocate the memory for each element before inserting, so I don't know the issue.
Anyone have a clue? Thanks.
struct word{
char *word;
struct word *next;
};
struct word *hashTable[20];
void func(const char *file)
{
char word[1000];
int i;
FILE *infile = stdin;
infile = fopen(file, "rb");
if(infile == NULL) {
printf("cannot open [%s]\n", file);
return;
}
while(fscanf(infile, "%s" word) != EOF) {
struct word *w;
w = malloc( sizeof( struct word ));
w->word = word;
w->next = NULL;
insert(w);
}
fclose (infile);
}
void insert(struct word *v)
{
if( hashTable[hash(v->word)] )
{
struct word *end = hashTable[hash(v->word)];
while(end->next != NULL ) {
end = end->next;
}
end->next = v;
}
else
hashTable[hash(v->word)] = v;
}
That's because you set the word pointer of every struct word to point at the same word array (the one defined as a local variable in func). This array gets overwritten with each word from the file, so they'll all end up being the same. You need to allocate more space for each word array you want to keep, and copy it there. The strdup function will do that nicely for you if you change it to be
w->word = strdup(word);

Resources