#include <stdio.h> // for printf(), fopen(), fclose(), stdin, stdout,
// getc(), putc(), FILE, EOF, NULL, FILENAME_MAX, FOPEN_MAX
void filecopy(FILE *, FILE *);
// concatenate files, version 1
int main(int argc, char *argv[])
{
// printf("FILENAME_MAX: %d\n", FILENAME_MAX);
// printf("FOPEN_MAX: %d\n", FOPEN_MAX);
FILE *fp;
if (argc == 1) // no command-line args, just program name
{ // copy standard input to standard output
filecopy(stdin, stdout);
return 0; // end program normally
}
// else
while (--argc > 0) // for all args except program name
{ // open file for reading
if ((fp = fopen(*++argv, "r")) == NULL)
{
printf("cat1: can't open \"%s\"\n", *argv);
return 1; // end program, signalling error
}
// else // fp != NULL, file open
filecopy(fp, stdout);
fclose(fp); // close file, free fp
}
return 0;
}
// copy from ifp (input) to ofp (output)
void filecopy(FILE *ifp, FILE *ofp)
{
int c;
while ((c = getc(ifp)) != EOF)
{putc(c, ofp);}
}
/*
gcc cat1.c -o cat1
./cat1
// FILENAME_MAX: 4096 // max chars in a file name
// FOPEN_MAX: 16 // max no of files open at the same time
Hello! // Enter
Hello!
What's up? // Enter
What's up?
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
./cat1 cat1.c
./cat1 cat1.c cat1.c
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // for fprintf(), fopen(), fclose(), ferror(),
// getc(), putc(), stdin, stdout, stderr, FILE, EOF, NULL
#include <stdlib.h> // for exit()
void filecopy(FILE *, FILE *);
// concatenate files, version 2
int main(int argc, char *argv[])
{
FILE *fp;
char *prog = argv[0]; // program name
if (argc == 1) // no command-line args, just program name
{ // copy standard input to standard output
filecopy(stdin, stdout);
exit(0); // end program normally
}
// else
while (--argc > 0) // for all args except program name
{ // open file for reading
if ((fp = fopen(*++argv, "r")) == NULL)
{
fprintf(stderr, "%s: can't open \"%s\"\n", prog, *argv);
exit(1); // end program, signalling error
}
// else // fp != NULL, file open
filecopy(fp, stdout);
fclose(fp); // close file, free fp
}
if (ferror(stdout))
{
fprintf(stderr, "%s: error writing stdout\n", prog);
exit(2); // end program, signal other error code
}
exit(0); // end program normally
}
// copy from ifp (input) to ofp (output)
void filecopy(FILE *ifp, FILE *ofp)
{
int c;
while ((c = getc(ifp)) != EOF)
{putc(c, ofp);}
}
/*
gcc cat2.c -o cat2
./cat2
Hello! // Enter
Hello!
What's up? // Enter
What's up?
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
./cat2 cat2.c
./cat2 cat1.c cat2.c
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
Exercise 7-6. Write a program to compare two files, printing the first line where they differ.
#include <stdio.h> // for fprintf(), fopen(), fclose(), ferror(),
// getc(), putc(), stdin, stdout, stderr, FILE, EOF, NULL
#include <string.h> // for strlen(), strcmp()
#include <stdlib.h> // for exit()
#define MAXLINE 1000
// get at most n-1 chars from fp:
char * fGets(char *s, int n, FILE *fp); // fgets() is in stdio.h
// write string line on stdout:
int writeLine(char *line);
int main(int argc, char *argv[])
{
if (argc != 3)
{
fprintf(stderr, "Usage: %s file1 file2\n", argv[0]);
exit(1); // end program, signalling error
}
FILE *fp1, *fp2;
fp1 = fopen(argv[1], "r");
fp2 = fopen(argv[2], "r");
if (fp1 == NULL || fp2 == NULL)
{
fprintf(stderr, "%s: can't open \"%s\" or \"%s\"\n",
argv[0], argv[1], argv[2]);
exit(1); // end program, signalling error
}
char line1[MAXLINE], line2[MAXLINE];
int lineno = 0;
while (fGets(line1, MAXLINE, fp1) != NULL &&
fGets(line2, MAXLINE, fp2) != NULL)
{
lineno++;
if (strcmp(line1, line2)) // not 0
{
fprintf(stderr, "%s: line %d:\n", argv[0], lineno);
fprintf(stderr, "%s: %s", argv[1], line1);
// writeLine(line1);
fprintf(stderr, "%s: %s", argv[2], line2);
// writeLine(line2);
break; // exit(0);
}
}
fclose(fp1), fclose(fp2);
exit(0);
}
// get at most n-1 chars from fp:
char * fGets(char *s, int n, FILE *fp) // fgets() is in stdio.h
{
register int c;
register char *cs;
cs = s;
while (--n > 0 && (c = getc(fp)) != EOF)
{
if ((*cs++ = c) == '\n')
{break;}
}
*cs = '\0';
return (c == EOF && cs == s) ? NULL : s;
}
// read a line, return length:
int getLine(char *line, int max) // getline() is in stdio.h
{
if (fGets(line, max, stdin) == NULL)
{return 0;}
// else
return strlen(line); // sizeof(line)
}
// put string s on file fp:
int fPuts(char *s, FILE *fp) // fputs() is in stdio.h
{
int c;
while (c = *s++)
{putc(c, fp);}
return ferror(fp) ? EOF : 0;
}
int writeLine(char *line)
{
return fPuts(line, stdout);
}
/*
gcc diff2.c -o diff2
./diff2
Usage: ./diff2 file1 file2
./diff2 cat.c cat1.c
./diff2: can't open "cat.c" or "cat1.c"
diff cat1.c cat1.c
./diff2 cat1.c cat1.c
// no output (files are identical)
./diff2 cat1.c cat2.c
./diff2: line 1:
cat1.c: #include <stdio.h> // for printf(), fopen(), fclose(), stdin, stdout,
cat2.c: #include <stdio.h> // for fprintf(), fopen(), fclose(), ferror(),
diff cat1.c cat2.c
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
Exercise 7-7. Modify the pattern_finding_program of Chapter_5 to take its input from a set of named files or, if no files are named as arguments, from the standard input. Should the file name be printed when a matching line is found?
Ah Love! could you and I with Fate conspire
To grasp this sorry Scheme of Things entire,
Would not we shatter it to bits -- and then
Re-mould it nearer to the Heart's Desire!
#include <stdio.h> // for fprintf(), putchar(), fopen(), fclose(),
// ferror(), getc(), putc(), stdin, stdout, stderr, FILE, EOF, NULL
#include <string.h> // for strlen(), strstr()
#include <stdlib.h> // for exit()
#define MAXLINE 1000
// get at most n-1 chars from fp:
char * fGets(char *s, int n, FILE *fp); // fgets() is in stdio.h
// read a line, return length:
int getLine(char *line, int max); // getline() is in stdio.h
// write string line on stdout:
int writeLine(char *line);
int main(int argc, char *argv[])
{
char *prog = argv[0]; // initialize
FILE *fp = stdin; // default value
char *pattern = "ould"; // default value
char line[MAXLINE];
int lineno = 0;
if (argc >= 2) {pattern = argv[1];}
if (argc < 3)
{
printf("%s: search for pattern \"%s\" in \"stdin\":\n",
prog, pattern);
while(getLine(line, MAXLINE) > 0)
{
lineno++;
if (strstr(line, pattern) != NULL)
{
printf("%d: ", lineno);
writeLine(line);
}
}
exit(0); // end program normally
}
// here argc >= 3 and pattern == argv[1]
argc -= 2, argv += 2;
for ( ; argc-- > 0; argv++)
{
lineno = 0; // reset
fp = fopen(*argv, "r");
if (fp == NULL)
{
fprintf(stderr, "%s: can't open \"%s\"\n", prog, *argv);
exit(1); // end program, signalling error
}
printf("%s: search for pattern \"%s\" in \"%s\":\n",
prog, pattern, *argv);
while(fGets(line, MAXLINE, fp) != NULL)
{
lineno++;
if (strstr(line, pattern) != NULL)
{
printf("%d: ", lineno);
writeLine(line);
}
}
putchar('\n');
fclose(fp);
}
if (ferror(stdout))
{
fprintf(stderr, "%s: error writing stdout\n", prog);
exit(2); // end program, signal other error code
}
exit(0);
}
// get at most n-1 chars from fp
char * fGets(char *s, int n, FILE *fp) // fgets() is in stdio.h
{
register int c;
register char *cs;
cs = s;
while (--n > 0 && (c = getc(fp)) != EOF)
{
if ((*cs++ = c) == '\n')
{break;}
}
*cs = '\0';
return (c == EOF && cs == s) ? NULL : s;
}
// read a line, return length:
int getLine(char *line, int max) // getline() is in stdio.h
{
if (fGets(line, max, stdin) == NULL)
{return 0;}
// else
return strlen(line); // sizeof(line)
}
// put string s on file fp:
int fPuts(char *s, FILE *fp) // fputs() is in stdio.h
{
int c;
while (c = *s++)
{putc(c, fp);}
return ferror(fp) ? EOF : 0;
}
int writeLine(char *line)
{
return fPuts(line, stdout);
}
/*
gcc pattern.c -o pattern
./pattern ink
./pattern: search for pattern "ink" in "stdin":
I think therefore I am
1: I think therefore I am
I am therefore I think
2: I am therefore I think
I like rain
The rain in Spain stays mainly in the plain
Ink is a dye
Brink! is about skating
6: Brink! is about skating
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
./pattern < Khayam.txt
./pattern: search for pattern "ould" in "stdin":
1: Ah Love! could you and I with Fate conspire
3: Would not we shatter it to bits -- and then
4: Re-mould it nearer to the Heart's Desire!
./pattern ear < Khayam.txt
./pattern: search for pattern "ear" in "stdin":
4: Re-mould it nearer to the Heart's Desire!
./pattern cat cat1.c cat2.c
./pattern: search for pattern "cat" in "cat1.c":
6: // concatenate files, version 1
23: printf("cat1: can't open \"%s\"\n", *argv);
42: gcc cat1.c -o cat1
43: ./cat1
52: ./cat1 cat1.c
54: ./cat1 cat1.c cat1.c
./pattern: search for pattern "cat" in "cat2.c":
7: // concatenate files, version 2
48: gcc cat2.c -o cat2
49: ./cat2
56: ./cat2 cat2.c
58: ./cat2 cat1.c cat2.c
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
Exercise 7-8. Write a program to print a set of files, starting each new one on a new page, with a title and a running page count for each file.
#include <stdio.h> // for fprintf(), fopen(), fclose(), ferror(),
// getc(), putc(), printf(), stdin, stdout, stderr, FILE, EOF, NULL
#include <stdlib.h> // for exit()
#define PAGELINES 10 // no of lines in a page
#define MAXLINE 1000
void filecopy(FILE *, FILE *);
void prntitle(char *); // print title
// concatenate files, print title and page numbers
int main(int argc, char *argv[])
{
FILE *fp;
char *prog = argv[0]; // program name
if (argc == 1) // no command-line args, just program name
{ // copy standard input to standard output
prntitle("stdin");
filecopy(stdin, stdout);
exit(0); // end program normally
}
// else
while (--argc > 0) // for all args except program name
{ // open file for reading
if ((fp = fopen(*++argv, "r")) == NULL)
{
fprintf(stderr, "%s: can't open \"%s\"\n", prog, *argv);
exit(1); // end program, signalling error
}
// else // fp != NULL, file open
prntitle(*argv);
filecopy(fp, stdout);
fclose(fp); // close file, free fp
}
if (ferror(stdout))
{
fprintf(stderr, "%s: error writing stdout\n", prog);
exit(2); // end program, signal other error code
}
exit(0); // end program normally
}
void prntitle(char *title) // print title
{
printf("----------");
printf(" %s ", title);
printf("----------\n");
}
// get at most n-1 chars from fp:
char * fGets(char *s, int n, FILE *fp); // fgets() is in stdio.h
// put string s on file fp:
int fPuts(char *s, FILE *fp); // fputs() is in stdio.h
// copy from ifp (input) to ofp (output)
void filecopy(FILE *ifp, FILE *ofp)
{
int lineno = 0;
int pageno = 0;
char line[MAXLINE];
while (fGets(line, MAXLINE, ifp) != NULL)
{
lineno++;
if (lineno % PAGELINES == 1)
{
pageno++;
fprintf(ofp, "\nPage %d:\n", pageno);
}
fPuts(line, ofp);
}
putc('\n', ofp);
}
// get at most n-1 chars from fp
char * fGets(char *s, int n, FILE *fp) // fgets() is in stdio.h
{
register int c;
register char *cs;
cs = s;
while (--n > 0 && (c = getc(fp)) != EOF)
{
if ((*cs++ = c) == '\n')
{break;}
}
*cs = '\0';
return (c == EOF && cs == s) ? NULL : s;
}
// put string s on file fp:
int fPuts(char *s, FILE *fp) // fputs() is in stdio.h
{
int c;
while (c = *s++)
{putc(c, fp);}
return ferror(fp) ? EOF : 0;
}
/*
gcc catn.c -o catn
./catn // copy the text (15 lines with the newline at the end)
The Rain in Spain
Alan Jay Lerner
The rain in Spain stays mainly in the plain!
I think she's got it! I think she's got it!
The rain in Spain stays mainly in the plain!
By George, she's got it! By George, she's got it!
Now, once again where does it rain?
On the plain! On the plain!
And where's that soggy plain?
In Spain! In Spain!
Now once again, where does it rain?
On the plain! On the plain!
And where's that blasted plain?
In Spain! In Spain!
---------- stdin ----------// paste the text after this line in the terminal window
The Rain in Spain
Alan Jay Lerner
The rain in Spain stays mainly in the plain!
I think she's got it! I think she's got it!
The rain in Spain stays mainly in the plain!
By George, she's got it! By George, she's got it!
Now, once again where does it rain?
On the plain! On the plain!
And where's that soggy plain?
In Spain! In Spain!
Now once again, where does it rain?
On the plain! On the plain!
And where's that blasted plain?
In Spain! In Spain!
Page 1:
The Rain in Spain
Alan Jay Lerner
The rain in Spain stays mainly in the plain!
I think she's got it! I think she's got it!
The rain in Spain stays mainly in the plain!
By George, she's got it! By George, she's got it!
Now, once again where does it rain?
On the plain! On the plain!
And where's that soggy plain?
In Spain! In Spain!
Page 2:
Now once again, where does it rain?
On the plain! On the plain!
And where's that blasted plain?
In Spain! In Spain!
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
./catn cat1.c
---------- cat1.c ----------
Page 1:
..........
./catn cat1.c cat2.c
*/