• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 366
  • Last Modified:

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.
0
greyknight17
Asked:
greyknight17
  • 8
  • 6
  • 2
2 Solutions
 
imladrisCommented:
A standard difficulty in reading files into array's is that you often don't know how large the array needs to be to hold all the contents of the file.

But, assuming for the moment that the file is expected to have some specific number of lines, you could do something along the following lines:

char string[3][30] = { "sometext1",
                                 "sometext2",
                                 "sometext3"
                               }
char fstring[3][30];

void main(int argc,char *argv[])
{    FILE *fp;
     int i;

     fp=fopen("filename","r");
     if(fp==NULL)
     {     printf("couldn't open file");
           exit(0);
     }
     for(i=0; i<3; ++i)fgets(fstring[i],30,fp);
     fclose(fp);
     
     for(i=0; i<3; ++i)
     {    if(strcmp(string[i],fstring[i])!=0)printf("%s\n",string[i]);
     }
     return;
}


I wasn't exactly clear on what you wanted to do comparisonwise. This example simply compares each of the strings, and shows any of the "string"'s that are not matched in the file.
0
 
greyknight17Author Commented:
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.
0
 
PaulCaswellCommented:
Now things are a little clearer. You probably dont need to store the file at all. Just read each line, look it up in your list. If its not there, print it.

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

void main(int argc,char *argv[])
{    FILE *fp=fopen("filename","r");
     if(fp!=NULL)
     {
       char line[256];
       while ( fgets(file, line, sizeof(line)) != NULL )
       {
     int i;
     int ignoreThisOne = 0;
     for ( i = 0; !ignoreThisOne && i < sizeof(ignore) / sizeof(ignore[0]); i++ )
     {
       if ( stricmp ( line, ignore[i] ) == 0 ) ignoreThisOne = 1;
     }
     if ( !ignoreThisOne ) printf ( "%s\n", line );
       }
     fclose(fp);
     return;
}

The only thing left to do is to strip '\r' or '\n' off the end of 'line' before the comparison.

Paul
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
greyknight17Author Commented:
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?
0
 
imladrisCommented:
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.
0
 
greyknight17Author Commented:
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.
0
 
greyknight17Author Commented:
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
0
 
PaulCaswellCommented:
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.

0
 
PaulCaswellCommented:
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
0
 
greyknight17Author Commented:
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)?
0
 
PaulCaswellCommented:
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
0
 
greyknight17Author Commented:
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?
0
 
PaulCaswellCommented:
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
0
 
greyknight17Author Commented:
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?
0
 
PaulCaswellCommented:
>>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
0
 
greyknight17Author Commented:
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.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 8
  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now