> /****************************************************************/
> /* */
> /* Description : Find the difference between files */
> /* File : diff.c */
> /* Author : Lakshmi Narayana P */
> /* */
> /****************************************************************/
>
>
> #include <stdio.h>
#include <stdlib.h> /* for EXIT_* macros */
#include <string.h> /* You have used strcmp () */
> #define MAXLINE 2000
> #define MAXCHARINLINE 50
It is just a matter of your choice, but the program can be made
more readable. I would prefer the following style:
#define MAX_LINE 2000
#define MAX_CHAR_IN_LINE 50
>
> void storeline(FILE *fd, int *lines,char buf[][MAXCHARINLINE]);
>
> main(int argc,char *argv[]) {
The above definition of main is not portable to C99 compliant
compilers, but acceptable by C90 compilers. For maximum portability
of your program, use any of the following style of using main.
int main ( void );
or,
int main ( int argc, char *argv[] );
or
int main ( int argc, char **argv );
> FILE *first,*second;
> FILE *out;
>
> int i = 0 ,j = 0 ;
> int first_line = 0;
> int second_line = 0;
> int count = 0;
> char first_buf[MAXLINE][MAXCHARINLINE];
> char second_buf[MAXLINE][MAXCHARINLINE];
> char temp[MAXLINE][MAXCHARINLINE];
>
> if (argc != 3) {
> printf("\nUsage: < Main File > < Sub File>\n");
> printf("\nInsufficent arguments\n");
This is an error message for the user. Then you should prefer
using the error stream (stderr) to print the messages instead of
the regular one (stdout). Consider an example. You are redirecting
the output of a program to a file, which you would do like this:
$ ./a.out > file
Generally, only the stdout is redirected to the file, not the stderr.
And, error message, if any, is instantly displayed on the screen
since the stderr is still, by default, the screen. So use:
fprintf ( stderr, "\nUsage: < Main File > < Sub File>\n " );
fprintf ( stderr, "\nInsufficent arguments\n" );
> exit(0);
> }
If this application was launched by some other process, then the
zero, in the above exit() statement, is the return value of this
application. Zero is generally considered as a success in the
UNIX environment, but may not be on other systems! Since, you
are exiting because of an error, this zero may give a wrong
message to the parent process. Instead, use the two macros found
in the <stdlib.h>: EXIT_FAILURE and EXIT_SUCCESS. These macros
are defined by your compiler according to the system for which they
generate the executable. You may also consider returning the value
of `errno' if the parent and child processes agree so.
>
> first = fopen(argv[1],"r");
> if ( first == NULL) {
> perror("Failed to open");
> exit(0);
> }
>
> second = fopen(argv[2],"r");
> if ( second == NULL) {
> perror("Failed to open");
> exit(0);
> }
>
Same thing here: use
exit ( EXIT_FAILURE );
> out = fopen("target.txt","w");
> if ( out == NULL) {
> perror("Failed to open");
> exit(0);
> }
>
Why not make the the first argument of fopen() as argv[3]?
> storeline(first,&first_line, first_buf);
> storeline(second,&second_line, second_buf);
>
> for (i = 0; i <= first_line ; i++) {
> for (j = 0; j <= second_line; j++) {
> if (!(strcmp(first_buf[i],second_buf[j])))
> break;
> else if(j == second_line) {
> strcpy (temp[count],first_buf[i]);
> count++;
> }
> }
> }
>
> for (i = 0; i < count; i++)
> fprintf(out,"%s",temp[i]);
>
> printf("\nPlease have a view at target.txt file\n");
The above is about the algorithm you choose. I can't say much.
> close(first);
> close(second);
> close(out);
Oops!
fclose ( first );
fclose ( second );
fclose ( out );
return EXIT_SUCCESS; /* do not forget this */
> }
>
>
> void storeline(FILE *fd, int *lines,char buf[][MAXCHARINLINE]) {
I, generally, have heard it to be better to put the opening brace
of a function in it's own line. This may be helpful to tools which
operate on the souce codes.
> int ch,i = 0,j = 0;
>
> while((ch = fgetc(fd)) != EOF) {
This is OK.
> buf[i][0] = ch;
> while (1) {
> buf[i][j++] = ch;
> if (ch == '\n') {
> j = 0;
> (*lines)++;
> break;
> }
> ch = fgetc(fd);
> }
> i++;
> }
> }