Link to home
Start Free TrialLog in
Avatar of Member_2_921743
Member_2_921743Flag for United States of America

asked on

Read in file as array and compare...

Hi, I want to know how to write a C program that will compare a user's file with what I have in a array (in the c program code).  I want to compare my array with what the user file.  Is it ok to list each string in my array followed by a comma and then newline?  Like:

str {sometext1,
sometext2,
sometext3}

I want to store my own array of text (to match with what the user enters) in the program.

So if the user's file has sometext2, I want it to compare it with my array (which is there now), and it will not display that line.  Just display sometext1 and sometext3.

I'm sure there's a way to compare the array with the user file.  I was wondering how I could store each line in the user's file in another array and compare it with my array.  Would a for loop do the job or do I have to use strcompare?  I will be using FILE * to open the file to read and compare.

It's been a while since I programmed with C.  Just need a little help and it'll probably jog my memory.

Thanks.
SOLUTION
Avatar of imladris
imladris
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Member_2_921743

ASKER

Thanks imladris.

Seems so simple.  Could I use some sort of dynamic array to do this?  That way I don't need to keep count of how big the array should be.

I want to compare the user file with the array and display the ones that are not listed in my array.  How do I make it so that it's NOT case-sensitive?

I have my list in a text file now:

sometext1
sometext2
sometext3

Is there an easy way to make this an array?  I mean, I have to enclose this whole list in quotes and add commas to them, which will be very tedious (especially for the filesize I deal with).

Thanks.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks for the reply Paul.  Are these errors:

while ( fgets(file, line, sizeof(line)) != NULL )  <-- Do I substitute the filename for the "file" parameter

for ( i = 0; !ignoreThisOne && i < sizeof(ignore) / sizeof(ignore[0]); i++ )  <-- For the second part (!ignoreThisOnce), do I need to put "i!=ignore..." or will it work without the 'i'

"The only thing left to do is to strip '\r' or '\n' off the end of 'line' before the comparison."
Don't know what you mean here.  What is it for?

I haven't tried testing out either code yet, but is the compare case-sensitive?

If I wanted to output this to an external file, would it work if I just replaced the following:

   if ( !ignoreThisOne ) printf ( "%s\n", line );

With
      FILE *fp1=fopen("output.txt","w");
      if ( !ignoreThisOne ) fprintf ( "%s\n", fp1);

Would that work?
No. The parameters seem to be in the wrong order. As far as I can tell, that line should be:


       while ( fgets(line, sizeof(line),fp) != NULL )

It will work without the i!=ignoreThisOne. ignoreThisOne is serving as a flag to indicate whether you have found the string in your list or not. It will be perceived as true if it is non-zero, and false otherwise. So !ignoreThisOne will be true (and the loop will continue to execute) as long as ignoreThisOne is 0. Once it is set to 1 it will become false, and the loop will terminate.

When fgets reads from the file it will include the terminating newline character. Since this newline character is not in your array to compare against, you would never be able to get a match. To be able to get the matches you expect you must eliminate that final character. Something like:


       while ( fgets(file, line, sizeof(line)) != NULL )
       {
     int i;
     int ignoreThisOne = 0;
     line[strlen(line)-1]='\0';  //  <-- delete last character
     for ( i = 0; !ignoreThisOne && i < sizeof(ignore) / sizeof(ignore[0]); i++)

should do the trick.

Yes that should work to go to a file. The fopen should happen by the first one, of course, and you should remember to close it too.
I edited it yesterday and forgot to bring it with me today.  It runs but not sure if it works properly.  Below is the code (or should be similar to what I did yesterday night):

void main(int argc,char *argv[])
{    FILE *fp=fopen("filename","r");
     FILE *fp1=fopen("output.txt","w");

char * ignore[] = { "sometext1",
                                 "sometext2",
                                 "sometext3"
                               }

     if(fp!=NULL)
     {
       char line[256];
       while ( fgets(file, line, sizeof(line)) != NULL )
       {
     int i;
     int ignoreThisOne = 0;
     line[strlen(line)-1]='\0';  //  <-- delete last character
     for ( i = 0; !ignoreThisOne && i < sizeof(ignore) / sizeof(ignore[0]); i++)
     {
       if ( stricmp ( line, ignore[i] ) == 0 ) ignoreThisOne = 1;
     }
      if ( !ignoreThisOne ) fprintf ( "%s\n", fp1);
       }
     fclose(fp);
     return;
}


I added the stdio and string libraries also (didn't put it on top).  It created the exe and I double clicked on it.  Nothing happened.  I created a file called filename and put:

sometext2

in it.  Saved it and then ran the program in the same directory.  The file output.txt is created, but nothing is in the file.  I want output.txt to contain:

sometext1
sometext3

after I run the exe file.  I hope the above coding is identical to what I did last night.  I didn't edit anything much so it should be similar.  I'm using Visual C++ to compile the code - I don't think this really matters though, just wanted to give the info out.
I did a little more editing yesterday and got it to work - somewhat.  The outputted file just displays (null)  What's wrong here?

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

void main(int argc, char *argv[]){

    FILE *fp = fopen("1.txt", "r");
    FILE *fp1 = fopen("test.txt", "w");

    char * ignore[] = {"sometext1",
                       "sometext2",
                       "sometext3"};
    if(fp!=NULL){
        char line[256];
        while (fgets(line, sizeof(line),fp) != NULL){
            int i;
            int ignoreThisOne = 0;
            //line[strlen(line)-1] = '\0';  //  <-- delete last character
                for (i = 0; !ignoreThisOne && i < sizeof(ignore) / sizeof(ignore[0]); i++){
                    if (strcmp(line, ignore[i]) == 0) ignoreThisOne = 1;
                }//end for
            if (!ignoreThisOne) fprintf(fp1, "%s\n");
        }//end while
        fclose(fp);
        fclose(fp1);
        return;
    }//end if statement
}//end main
If you want your output to contain:

sometext1
sometext3

then these strings must NOT be in the ignore list. What is in your "1.txt" input file?

Have you got a debugger you can use? A great deal of what is going on will become clear when you run the program under a debugger.

Paul

P.S.

//line[strlen(line)-1] = '\0';  //  <-- delete last character
This line is required because 'fgets' puts a '\r' on the end of the string it reads from the file. You've commented it out. This might stop it working.

I must have been having a bad day when I posted my suggestion!!!

Thanks imladris for pointing out my parameter error with the fgets function.

There's another one here:

     if ( !ignoreThisOne ) fprintf ( "%s\n", fp1);
 
This should read:

     if ( !ignoreThisOne ) fprintf ( fp1, "%s\n", line);
 
Sorry!!


Paul
Thanks Paul.  I think it worked now with the changes you told me to make.  Just have some slight things now.  The 1.txt file has this:

sometext2
testing
123
k
sometext
sometext3
sometext4
sometext1

My test.txt file has

testing
123
k
sometext
sometext4
sometext

Why is there an extra sometext at the end of the text.txt file?  If anything it should be sometext1 (but that's in the ignore list - so I know why it's not listed).

Just that little problem above is bugging me.  Anyway to fix it so that sometext in the text.txt file won't show up (because in 1.txt it's listed as sometext1 and not sometext)?

I'm using Visual C++.  How can I debug if (if it's needed at all now that it's fixed for the most part)?
Its because of the deletion of the last character of a line. There is only a '\r' at the end of teh string if there was a '\n' code of some sort at the end of the line in the file. If there isnt a CR at the end of the file this code will fail.

Change the line to:

if ( line[strlen(line)-1] == '\r' ) line[strlen(line)-1] = '\0';  //  <-- delete last character if its a '\r'.

>>How can I debug...
The easiest way is to set some break points and hit <F5>.


Paul
Don't know what happened here, but now the output (test.txt) has this:

sometext2

testing

123

k

sometext

sometext3

sometext4

It's skipping a line.  I guess this is only a minor glitch.  It just deletes the last character only right and nothing else?
Try:

if ( line[strlen(line)-1] == '\n' ) line[strlen(line)-1] = '\0';  //  <-- delete last character if its a '\r'.

It sometimes depends on whether the file is open in binary mode or not.

Have a go with the debugger and see what you can find.

Paul
That worked now.  When I got home I inputted some data that the user will actually have in the text file.  Had some other problems with it.  The problem is that I have file paths and parameters in the text.  Another words with special characters like '\', '/' and even double quotes.  So what I did was replace them with a \ in front of each.  That seems to take away my errors and warnings, but it still won't work.  The test.txt output file is not filtering them out correctly.

What changes to the code needs to be made so that it's "not" case-sensitive when comparing?
>>What changes to the code needs to be made so that it's "not" case-sensitive when comparing?
Instead of using:

strcmp

use:

stricmp

Paul
Sweeeeet.  That was in there originally but I thought it was an misspelling so I took it out.

I have another question on how to use another text file instead of the array to compare it with the user's text file, but I think it's enough work for now.  I will probably start a new thread for that one.   Unless you have time to help out with this one also?

I will issue the ponts now.