questioner
questioner

Reputation: 33

Access violation when searching through a file

This is my algorithm for searching a term into a file.

void ricerca_file(char* frase){

char* prelievo = "";
file = fopen("*userpath*\\file.bin", "rb");
while((fgets(prelievo, sizeof(prelievo), file)) != NULL){
    if((strstr(prelievo, frase)) != NULL)
        printf("frase trovata!\n");
} 

fclose(file);
printf("%s", prelievo);}

i ask the input of frase in this way:

char* frase = "";
printf("insert the term that you want to search..");
scanf("%s", frase);

and then i call the function with:

ricerca_file(frase);

The compiler gives me this error after i write the input (e.g the number 2):

prove1.exe: 0xC0000005: Access violation writing location 0x00F67BC3.

If there is a handler for this exception, the program may be safely continued.

What am i doing wrong?

if it wasn't clear, i'm learning. But i didn't really got how to manage the search of a term into a file. I guess that with this algorithm i can miss lots of matches because if i search for "hello", with the strstr function that moves 5 characters per cycle if i have a file with a text like this "abchelloabc" he will first find "abche" and will not find anything, while after the first cycle it will go to the "lloab" part and then "c". Am i right thinking that it works like that and this is wrong?

Upvotes: 1

Views: 189

Answers (4)

Michi
Michi

Reputation: 5297

This answer is not exactly related to your problem, but because you already got your Answers i will try to explain you about some problems if you ignore them.

If we do not check for errors/return and the program works fine this does not mean that the program is ok or safe. Let's take the following scenario as an Example.

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

char *printFile(char *fileName){
    size_t length,size;
    char *buffer;
    FILE *file;

    file = fopen (fileName , "r" );


    fseek (file , 0 , SEEK_END);
    length = (size_t)ftell (file);
    fseek (file , 0 , SEEK_SET);

    buffer = malloc(length);
    if (buffer == NULL){
        fputs ("Memory error",stderr);
        exit (2);
    }


    size = fread (buffer,1,length,file);
    if (size != length){
        fputs ("Reading error",stderr);
        exit(3);
    }

    fclose (file);
    return buffer;
}

int main (void) {
    char *fileName = "test.txt";
    char *stringToSearch = "Addams";
    char *fileContent = printFile(fileName);

    if (strstr(fileContent, stringToSearch)){
        printf("%s was Found\n",stringToSearch);
    }else{
        printf("%s was not Found\n",stringToSearch);
    }

    free(fileContent);

    return 0;
}

The file test.txt has the following content:

Michael Jackson
Bryan Addams
Jack Sparrow

So now if I run this program I get:

Addams was Found

Everything seems to be ok, but what happens if I try to share this program with someone ? Or what happens if I try to run it on another computer ? well:

Segmentation fault (core dumped)

OMG, what did just happen now ? Simple,the file test.txt is missing and i did not check that in my program that's why.

Lets move on and create that file and run that program again:

Addams was not Found

Huh, I succeeded isn't ? Well not, valgrind has another opinion:

==3657== Invalid read of size 1
==3657==    at 0x4C32FF4: strstr (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3657==    by 0x400A2D: main (in /home/michi/program)
==3657==  Address 0x54202b0 is 0 bytes after a block of size 0 alloc'd
==3657==    at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3657==    by 0x40095E: printFile (in /home/michi/program)
==3657==    by 0x400A16: main (in /home/michi/program)

What happens is that I try to read a file which was newly created without thinking if that file has some content and i performed a lot of codding on it.

Upvotes: 0

user3629249
user3629249

Reputation: 16540

what am I doing wrong:

regarding:

char* prelievo = "";
file = fopen("*userpath*\\file.bin", "rb");
while((fgets(prelievo, sizeof(prelievo), file)) != NULL){
    ...

The call to fgets() needs to have a pointer to a buffer as its' first parameter.

The 'prelievo' is only an uninitalized pointer.

suggestion 1)

char* prelievo = malloc( 1024 );
if ( prelievo ) {
    file = fopen("*userpath*\\file.bin", "rb");
    while((fgets(prelievo, sizeof(prelievo), file)) != NULL){

suggestion 2)

char prelievo[1024];
file = fopen("*userpath*\\file.bin", "rb");
while((fgets(prelievo, sizeof(prelievo), file)) != NULL){

Upvotes: 0

Paul Roub
Paul Roub

Reputation: 36438

prelievo points to a string literal. This is constant data that cannot be written to. And sizeof(prelievo) will be 2 or 4 (or whatever size pointers are on your system), which is not what you want.

You'll need to instead point prelievo to an array of characters that can be modified:

char prelievo[1000];

The same problems and solution apply to frase:

char frase[1000];

Upvotes: 4

fuz
fuz

Reputation: 93034

You need to actually provide memory to save the string you scan into. Try something like this instead:

char frase[80];
printf("insert the term that you want to search..");
fgets(frase, 80, stdin);

This allocates enough space for 80 characters and then reads one line of input.

Please also check the results of all these functions: If they return an error, you should act appropriately.

Upvotes: 0

Related Questions