Reputation: 950
I'm training myself with c, my goal is to read the file and check if there is a given sentence inside of it. The function has to return "found" or "not found" respectively if the given sentence exists in the file or not.
The sentences are divided by a /
symbol.
Example of file:
1,2,3,4/
car, house, hotel/
2,age,12/
1,2/
1,2,3,5/
house, car/
Example of word to look for:
1,2/
My idea is to take each time a sentence from the file and put it in an array (called ary), check if the array (ary) is equal to the array (called sentence) that contains the given sentence that I'm looking for, and reuse that array (ary) for the next sentence in the file.
I've written this code:
#include <stdio.h>
void main()
{
char *sentence;
FILE *my_file;
char *ary;
int size = 500;
int got;
int ind=0;
int rest;
int found=0;
sentence="1,2";
my_file=fopen("File.txt", "r");
if(my_file==NULL)
{
printf("I couldn't open the file\n");
}
else
{
ary = (char*)malloc(500*sizeof(char));
while((got=fgetc(my_file))!=EOF)
{
if(got!='/')
{
ary[ind++]=(char)got;
}
else
{
ary[ind++]='\0';
rest = compare(sentence,ary);
if(rest==0)
{
found =1;
printf("found\n");
return;
}
ind=0;
free(ary);
ary = (char*)calloc(500, sizeof(char));
}
}
if(found==0)
{
printf("not found\n");
}
fclose(my_file);
}
}
int compare(char str1[], char str2[])
{
int i = 0;
int risp;
if(str1>str2 || str1<str2)
{
risp=-1;
}
if(str1==str2)
{
while(str1[i++]!='\0')
{
if(str1[i]!=str2[i]) risp=1;
}
}
return risp;
}
It compiles, but doesn't work properly and I don't find out why. Can someone please point out my mistakes or let me know of a better solution?
Edit: When I print the two str that relative to the sentence is ok, but the other one after the first print continues printing with a break in front of the words. Like the following:
Str1:1,2
Str2:1,2,3,4
Str1:1,2
Str2:
car, house, hotel
Str1:1,2
Str2:
2,age,12
Str1:1,2
Str2:
1,2
Str1:1,2
Str2:
1,2,3,5
Str1:1,2
Str2:
house, car
Can be this one of my problem? I tryed to solve it...
Upvotes: 2
Views: 187
Reputation: 950
Slowly slowly I found also a solution by myself. I know that is not elegant, but it's a little victory for me.
char c;
char str[]="1,2/";
FILE * f;
int i=0;
f=fopen("File.txt", "r");
if (f==NULL) perror ("Error opening file");
else
{
while ((c=(char)fgetc(f)) != EOF) {
if((c==str[i])) {
if (c=='/')
{
printf("FOUND\n");
return;
}
i++;
}
else i=0;
if(c=='/')
i=0;
}
printf("NOT FOUND\n");
fclose (f);
}
Upvotes: 1
Reputation: 11963
Moving pieces of strings around in C is definitely do-able, but it's finnicky, because you really have to understand how pointers and allocation are working behind the scenes. So can I suggest another approach that doesn't involve moving pieces of strings around?
First - let's write down a definition in psuedocode of how to find a string in a file:
def file_contains_string(file, string):
if (file is empty):
return "not found"
else if (initial_part_of_file_equals(file, string)):
return "found it!!!"
else
return file_contains_string(drop_first_character(file), string)
i.e. "the file contains the string if the first part of the file is equal to the string, or some later part of the file is equal to the string."
Here is a translation into C:
int file_contains_string(FILE *file, char *str)
{
if (feof(file)) return 0;
if (initial_part_of_file_equals(file, str)) return 1;
fgetc(file); /* discard leading character from the file */
return file_contains_string(file, str);
}
Now how do we implement initial_part_of_file_equals
? Well, the initial part of the file matches if the first characters are equal, and then the rest of the string matches the initial part of the file past the first character:
def initial_part_of_file_equals(file, string):
if is_empty(string):
return True
else if first_character(string) == first_character(file):
return initial_part_of_file_equals(drop_first_character(file),
drop_first_character(string))
else return False
How do we translate that? In C, a "string" is just a pointer to a character array, so you "drop the first character" of a string just by advancing the pointer. And you compare the first character of a string just by dereferencing the pointer.
int initial_part_of_file_equals(FILE * file, char * str)
{
if !(str*) return 1; /* Test for empty string */
if (feof(file)) return 0; /* Test for empty file */
char c = fgetc(file); /* get first character from file */
int result = (c == *str)
&& initial_part_of_file_equals(file, str++);
ungetc(c, file);
return result;
}
The ungetc
in there is important - if only the first part of str
matches, we want to make sure we don't actually consume the corresponding part of the input stream.
Upvotes: 1
Reputation: 14004
str1 and str2 are actually pointers (they refer to the memory location that the first element of the string is stored). So comparing str1 to str2 using > and == will only compare their memory locations. If they are at different locations (which they will), str1 and str2 will never be equal.
What you want to do is to step through both str1 and str2 and compare the values. I leave that as an exercise for the poster.
Upvotes: 2