Searching a key word at a file c - c

I had been trying to create a function that searches for a specific word at a file...My program compiles,but its execution is terminated at some point...
The function is:
void search(struct word *w,FILE *f)
{
char *c,*c2;
int i,j,n,k,l;
c=(char*)malloc(120*sizeof(char));
c2=(char*)malloc(20*sizeof(char));
while(f!=NULL)
{
j=0;
i=1;
fscanf (f,"%[^\n]%*c",c);
printf("%s",c);
n=strlen(c);
k=0;
l=j;
while(l<=n && *(c+j)!=' ')
{
*(c2+k)=*(c+j);
printf("1");
printf("%s",*(c2+k));
printf("2");
k=k+1;
l=l+1;
}
if(w->name==c2)
{
insert(i,j+1,name,&w);
}
else
{
if(l<n)
j=l+1;
k=0;
c2=(char*)malloc(20*sizeof(char));
l=j;
}
i=i+1;
j=0;
}
}
The main function is:
int main()
{
FILE *f;
struct word *s;
s=(struct word*)malloc(sizeof(struct word));
struct word *hashtable[100];
s->name=(char*)malloc(20*sizeof(char));
scanf("%s",s->name);
f=fopen("fileA.txt","rt");
char *name="fileA.txt";
search(s,f);
printresults();
system("pause");
return(0);
}
And the structs are:
struct position
{
char *filename;
int line;
int place;
struct position *next;
};
struct word
{
char *name;
struct word *right;
struct word *left;
struct position *result;
};
The program terminates between the printf("1") and printf("2").
What is wrong with my code?

If the crash happens somewhere between you print "1" and "2" it should be very easy to find, as there's only one statement there.
And it is easy to find:
printf("%s",*(c2+k));
The printf function is asked to print a string, but you pass a single character by using the dereference operator. That leads to undefined behavior when printf treats that single character as a pointer to a string.

Related

C : Binary tree infinite recursion problem

I can't seem to find where the problem is in my code, i'm essentially storing character patterns, if an existing pattern is already present I'll store it in the duplicate node, otherwise it will shift to the regular pattern one. The problem starts when i have a duplicate, it should move to the duplicate node, but instead loops infinitely.
The binary tree struct: :
struct arbre{
char id[10];
int length;
int token;
int count;
struct arbre *pattern;
struct arbre *doublon;
};
typedef struct arbre *Arbre;
The function to create and make new nodes
void ajouter(Arbre *a, char *tablettre, int length, int token){
if(*a==NULL){
*a=(Arbre)malloc(sizeof(struct arbre));
strcpy((*a)->id, tablettre);
//append((*a)->id,tablettre);
//printf("%s",(*a)->id);
(*a)->length = length;
(*a)->token = token;
(*a)->doublon=NULL;
(*a)->pattern=NULL;
}
if (strcmp((*a)->id, tablettre) == 0){ /// The problem is here
printf("%s",(*a)->doublon->id);
printf(" and %s",tablettre);
ajouter(&(*a)->doublon, tablettre, length, token);
}
if (strcmp((*a)->id, tablettre) != 0){
ajouter(&(*a)->pattern, tablettre, length, token);
}
}

Pointer of strings stored in linked list

I want to store words from a pointer of char strings in a double linked list. My function for storing the words in the char strings works perfect, but when it comes to storing in the dll elements it doesn't work anymore. I can't understand if there is a problem in the declarative zone of the list (I am new to lists, we just did some theory on them in the class) or with the node changing pointer.
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
int number_of_words (FILE *f) {
char x[1024];
int i=0;
while (fscanf(f, " %1023s", x) == 1) {
i++;
}
return i;
}
void words (FILE *f, char *words[]) {
char x[1024];
int i=0;
while (fscanf(f, " %1023s", x) == 1) {
words[i]=strdup(x);
i++;
}
}
typedef struct node{
int freq;
char *word_string;
struct node *next;
struct node *prev;
}node;
int main(int argc, const char * argv[]) {
FILE *input=fopen(argv[1], "r+");
if(input==NULL) printf("error in reading from file");
else printf("reading works.\n");
int k=number_of_words(input);
char *word[k];
char *word_unique[k];
rewind(input);
words(input, word);
int j=0,l=0,s=0;
for(j=0;j<k;j++) {
for (l=0; l<j; l++){
if (strcmp(word[j],word[l])==0)
break;
}
if (j==l){
word_unique[s]=word[j];
s++;
}
}
int *word_freq[s];
for(j=0;j<s;j++){
word_freq[j]=0;
}
for(j=0;j<s;j++) {
for (l=j; l<k; l++){
if (strcmp(word_unique[j],word[l])==0)
word_freq[j]++;
}
}
char *aux=malloc(30*sizeof(char));
for(j=0;j<s;j++){
for(l=j+1;l<s-1;l++){
if(strcasecmp(word_unique[j], word_unique[l])>0)
{
strcpy(aux,word_unique[j]);
strcpy(word_unique[j],word_unique[l]);
strcpy(word_unique[l],aux);
}
}
}
node *head, *curr=NULL;
int i=0;
head=NULL;
for(i=0;i<k;i++){
curr=(node *)malloc(sizeof(node));
curr->word_string=word_unique[i];
curr->freq=word_freq[i];
curr->next=head;
head=curr;
}
while(curr) {
if(curr->word_string!=NULL) printf("%s:%d\n", curr->word_string, curr->freq);
curr = curr->next;
}
return 0;
}
The input file is a text file and it looks like this:
Everything LaTeX numbers for you has a counter associated with it. The name of the counter
is the same as the name of the environment or command that produces the number, except
with no. Below is a list of some of the counters used in LaTeX’s standard document styles
to control numbering.
When I tried to print the unique elements in alphabetical order with their frequency, it actually prints out in reverse order with 4x frequency they actually have. It also separates "numbering." from the others + a new line at the beginning which I don't know where it comes from. This is what it prints:
reading works.
0- :2098416
numbering.:4
you:4
with:4
used:4
to:4
the:4
The:4
that:4
styles:4
standard:4
some:4
same:4
produces:4
or:4
of:4
numbers:4
number,:4
no:4
name:4
list:4
LaTeX’s:4
LaTeX:4
it.:4
is:4
in:8
has:24
for:16
except:8
Everything:4
environment:4
document:8
counters:4
counter:8
control:8
command:4
Below:4
associated:4
as:4
a:4
\.:4
Program ended with exit code: 0

Program with array of structs crashes

I have an array with multiple structs. When i ask the user to enter data the first time everything works but when i ask again for the next position in the array the program crashes. If this method doesn't work souldn't the program crash in the beginning? Is something wrong with malloc?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student {
char name[50];
int semester;
};
struct prof {
char name[50];
char course[50];
};
struct student_or_prof {
int flag;
int size;
int head;
union {
struct student student;
struct prof prof;
}
}exp1;
struct student_or_prof *stack;
void init(int n)
{
stack = malloc(n);
}
int push(struct student_or_prof **pinx,int *head,int n)
{
char name[50];
printf("\nn= %d\n",n);
printf("\nhead= %d\n",*head);
if(*head==n)
{
printf("Stack is full.\n");
return 1;
}
char x;
printf("Student or Professor? [s/p] ");
getchar() != '\n';
scanf("%c",&x);
if(x=='s')
{
getchar() != '\n';
pinx[*head]->flag = 0;
printf("\n\nGive student's name: ");
fgets(pinx[*head]->student.name,sizeof(pinx[*head]->student.name),stdin);
printf("\nGive student's semester: ");
scanf("%d",&(pinx[*head]->student.semester));
printf("\nName = %s\tSemester = %d",pinx[*head]->student.name,pinx[*head]->student.semester);
}
else if(x=='p')
{
getchar() != '\n';
pinx[*head]->flag = 1;
printf("\n\nGive professor's name: ");
fgets(pinx[*head]->prof.name,sizeof(pinx[*head]->prof.name),stdin);
printf("\nGive course: ");
fgets(pinx[*head]->prof.course,sizeof(pinx[*head]->prof.course),stdin);
printf("\nName = %s\tCourse = %s\n",pinx[*head]->prof.name,pinx[*head]->prof.course);
}
(*head)++;
printf("\nhead= %d\n",*head);
}
int main()
{
int n,i;
printf("Give size: ");
scanf("%d",&n);
init(n);
for(i=0;i<n;i++)
push(&stack,&exp1.head,n);
return 0;
}
You need to malloc the structure not n
malloc(sizeof(struct student_or_prof)*n)
EDIT:
And your code crashes again because pinx is a double pointer, so this operation is not valid:
pinx[*head]->flag = 0;
this is equivalent to:
*(pinx + *head)->flag = 0;
Since you are not changing what stack points to, you are better off using a single pointer instead of a double pointer.
So instead you should change your push API:
int push(struct student_or_prof *pinx,int *head,int n)
and call it like:
push(stack,&exp1.head,n);
malloc allocates the given number of bytes.
You have to multiply n with the size of your struct, to allocate enough memory.
pinx does not point to an array, so pinx[*head] is going to access invalid memory unless *head is zero.
I think you meant (*pinx)[*head] , which accesses the N-th element of the array you allocated via malloc. For example (*pinx)[*head].prof.name etc.
BTW, your head number doesn't seem to be used at all, except for exp1.head, maybe it'd be better to remove head from the struct, and just have a single variable head?

word counter 'forgetting' about already saved word

The snippets below are from my program that gets words, then prints them with the number of occurences.
It works almost fine except for it "forgots" that particular entry has been saved before and does NOT increment counter associated with it.
typedef struct {
char *word;
int occ;
}
words;
words *data=NULL;
int main(int argc, char **argv)
{
char *word;
words *temp;
int c,i,num;
words *ptr = NULL;
num=0;
while(1)
{
c=fgetc(infile);
if(c==EOF) break;
if(!isalpha(c)) continue;
else ungetc(c,infile);
word=getword(infile);
if(findword(word))
{
if(!(temp=realloc(data,sizeof(words)*(num+1))))
{ /* error handling */ }
else
data=temp;
}
else
free(word);
}
/* sort procedure here, irrelevant for the purpose of topic */
for(i=0;i<num;i++)
{
/*printf*/
}
return 0;
}
What's wrong with that code?
Thanks in advance!
The fundamental problem is that your "findword" function isn't actually finding a word; it's just looking at one item in the list. It needs to loop.
if ((strcmp(word, ptr->word)) == 0) {
//Do something to store the count
}
else {
return ptr;
}

program to find individual word count in a para

This is program to count individual word count in a variable para as an input.
I tried this by using linked list.
Here variable complete is an array that acts like a hash code and stores all alphabets and I am linking new word as per the hash and if there is same word then I am increasing the count. This is the logic I followed.
But the thing is in the program it is not going into a particular part of the code which is written to take repeated words and it is not increasing the count.
This is my code can any one help me with this.
#include<stdio.h>
#include<conio.h>
#include<string.h>
#define NULL 0
struct wordcount
{
char *s;
int count;
struct wordcount *next;
};
struct checkletter
{
char alph;
struct wordcount *next;
};
struct wordcount * create(char *);
main()
{
char *c,*s1,*intm;
char hastlet;
int hash[26],len,i,k=0,r,j,m=0,t,flag=0;
struct checkletter complete[26];
struct wordcount *node;
clrscr();
for(r=0;r<=25;r++)
{ complete[r].alph=r+97;
complete[r].next=NULL;
}
for(r=0;r<=25;r++)
{
printf("%c",complete[r].alph);
}
printf("\n");
printf("Enter the para :");
gets(c);
len=strlen(c);
//arranging the words and putting them with count
for(i=0;i<len;i++)
{ k=0;
intm='\0';
if(c[i]==' ')
{ for(j=m;j<i;j++)
{
intm[k]=c[j];
k++;
}
intm[k]='\0';
strcpy(s1,intm);
m=k;
m++;
hastlet=s1[0];
for(t=0;t<26;t++)
{
if(complete[t].alph==hastlet)
{
node=complete[t].next;
if(node==NULL)
{
complete[t].next=create(s1);
node=complete[t].next;
break;
}
else
{ while(!strcmp(node->s,s1))
{
node=node->next;
if(node->next==NULL)
{ flag++;
break;
}
}
if(!strcmp(node->s,s1))
(node->count)+=1;
if(flag)
{ node->next=create(s1);
}
} break;
}
}
}
}
//displaying the word that are counted
for(i=0;i<26;i++)
{ node=complete[i].next;
if(complete[i].next!=NULL)
while(1)
{ printf("%s---%d",node->s,node->count);
if(node->next==NULL)
break;
}
}
getch();
}
struct wordcount * create(char *y)
{
struct wordcount *newnode;
newnode->s=y;
newnode->count=0;
newnode->next=NULL;
return newnode;
}
The following is incorrect:
char *c;
...
gets(c);
Using an un-initialized pointer c in gets function leads to a undefined behavior. You need to allocate memory for c which is one greater than the max number of characters you wish to store.
Same is the case with intm.
Also, use fgets in place of gets

Resources