开发者

Opening a file in C through a proccess

I am trying to create a a program that does the following actions:

  1. Open a file and read one line.

  2. Open another file and read another line.

  3. Compare the two lines and print a message.

This is my code:

#include <stdio.h>
#include <string.h>
int findWord(char sizeLineInput2[512]);

int main()
{
    FILE*cfPtr2,*cfPtr1;
int i;
    char sizeLineInput1[512],sizeLineInput2[512];
    cfPtr2=fopen("mike2.txt","r");
    // I open the first file
while (fgets(sizeLineInput2, 512, cfPtr2)!=NULL)
   // I read from the first 1 file one line 
{
 if (sizeLineInput2[strlen(sizeLineInput2)-1]=='\n')
            sizeLineInput2[strlen(sizeLineInput2)-1]='\0';
             printf("%s \n",sizeLineInput2);
             i=findWord(sizeLineInput2);

   //I call the procedure that compares the two lines

}
getchar();
    return 0;
}
int  findWord(char sizeLineInput2[512])
{
int x;
char sizeLineInput1[512];
File *cfPtr1;
cfPtr1=fopen("mike1.txt","r");

// here I open the second file

     while (fgets(sizeLineInput1, 512,cfPtr1)!=NULL)
     {
        if (sizeLineInput1[strlen(sizeLineInput1)-1]=='\n')
            sizeLineInput1[strlen(sizeLineInput1)-1]='\0';
        if (strcmp(sizeLineInput1,sizeLineInput2)==0)

//Here, I compare the two lines

        printf("the words %s and %s are equal!\n",sizeLineInput1,sizeLineInput2);
        else
        printf("the words %s and %s are not equal!\n",sizeLineInput1,sizeLineInput2);
        }
    fclose(cfPtr1);
    re开发者_JS百科turn 0;
}

It seems to have some problem with file pointers handling. Could someone check it and tell me what corrections I have to do?


Deconstruction and Reconstruction

The current code structure is, to be polite about it, cock-eyed.

You should open the files in the same function - probably main(). There should be two parallel blocks of code. In fact, ideally, you'd do your opening and error handling in a function so that main() simply contains:

FILE *cfPtr1 = file_open("mike1.txt");
FILE *cfPtr2 = file_open("mike2.txt");

If control returns to main(), the files are open, ready for use.

You then need to read a line from each file - in main() again. If either file does not contain a line, then you can bail out with an appropriate error:

if (fgets(buffer1, sizeof(buffer1), cfPtr1) == 0)
    ...error: failed to read file1...
if (fgets(buffer2, sizeof(buffer2), cfPtr2) == 0)
    ...error: failed to read file2...

Then you call you comparison code with the two lines:

findWord(buffer1, buffer2);

You need to carefully segregate the I/O operations from the actual processing of data; if you interleave them as in your first attempt, it makes everything very messy. I/O tends to be messy, simply because you have error conditions to deal with - that's why I shunted the open operation into a separate function (doubly so since you need to do it twice).

You could decide to wrap the fgets() call and error handling up in a function, too:

const char *file1 = "mike1.txt";
const char *file2 = "mike2.txt";

read_line(cfPtr1, file1, buffer1, sizeof(buffer1));
read_line(cfPtr2, file2, buffer2, sizeof(buffer2));

That function can trim the newline off the end of the string and deal with anything else that you want it to do - and report an accurate error, including the file name, if anything goes wrong. Clearly, with the variables 'file1' and 'file2' on hand, you'd use those instead of literal strings in the file_open() calls. Note, too, that making them into variables means it is trivial to take the file names from the command line; you simply set 'file1' and 'file2' to point to the argument list instead of the hard-wired defaults. (I actually wrote: const char file1[] = "mike1.txt"; briefly - but then realized that if you handle the file names via the command line, then you need pointers, not arrays.)

Also, if you open a file, you should close the file too. Granted, if your program exits, the o/s cleans up behind you, but it is a good discipline to get into. One reason is that not every program exits (think of the daemons running services on your computer). Another is that you quite often use a resource (file, in the current discussion) briefly and do not need it again. You should not hold resources in your program for longer than you need them.

Philosophy

Polya, in his 1957 book "How To Solve It", has a dictum:

  • Try to treat symmetrically what is symmetrical, and do not destroy wantonly any natural symmetry.

That is as valid advice in programming as it is in mathematics. And in their classic 1978 book 'The Elements of Programming Style', Kernighan and Plauger make the telling statements:

  • [The] subroutine call permits us to summarize the irregularities in the argument list [...]
  • The subroutine itself summarizes the regularities of the code.

In more modern books such as 'The Pragmatic Programmer' by Hunt & Thomas (1999), the dictum is translated into a snappy TLA:

  • DRY - Don't Repeat Yourself.

If you find your code doing the 'same' lines of code repeated several times, write a subroutine to do it once and call the subroutine several times.

That is what my suggested rewrite is aiming at.


In both main() and findWord() you should not use strlen(sizeLineInputX) right after reading the file with fgets() - there may be no '\0' in sizeLineInput2 and you will have strlen() read beyond the 512 bytes you have.

Instead of using fgets use fgetc to read char by char and check for a newline character (and for EOF too).

UPD to your UPD: you compare each line of mike2.txt with each line of mike1.txt - i guess that's not what you want. Open both files one outside while loop in main(), use one loop for both files and check for newline and EOF on both of them in that loop.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜