Simple implementation of reading files
passed as command line arguments
using fgetc - in other words cat
#include <stdio.h>
int main(int argc, char *argv[]) {
// go through a list of files specified on the command line
// printing their contents in turn to standard output
int argument = 1;
while (argument < argc) {
// FILE is an opaque (hidden type) defined in stdio.h
// "r" indicate we are opening file to read contents
FILE *stream = fopen(argv[argument], "r");
if (stream == NULL) {
perror(argv[argument]); // prints why the open failed
return 1;
}
// fgetc returns next the next byte (ascii code if its a text file)
// from a stream
// it returns the special value EOF if not more bytes can be read from the stream
int c = fgetc(stream);
// return bytes from the stream (file) one at a time
while (c != EOF) {
fputc(c, stdout); // write the byte to standard output
c = fgetc(stream);
}
argument = argument + 1;
}
return 0;
}
Simple example of cp command
copy contents of file specified as first argument
to file specified as 2nd argument
8/5//18
#include <stdio.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <source file> <destination file>\n", argv[0]);
return 1;
}
FILE *inputStream = fopen(argv[1], "r");
if (inputStream == NULL) {
perror(argv[1]); // prints why the open failed
return 1;
}
FILE *outputStream = fopen(argv[2], "w");
if (outputStream == NULL) {
// perror could be used for a better error message here
fprintf(stderr, "%s: open of '%s' failed\n", argv[0], argv[2]);
return 1;
}
int c = fgetc(inputStream);
while (c != EOF) {
fputc(c, outputStream);
c = fgetc(inputStream);
}
fclose(outputStream);
return 0;
}
Print lines containing specified pattern from the files specified as arguments
This version provides the unix filter behaviour
where if no files are specified it process stdin
Note this code will produce incorrect results if matched
lines contain >= MAX_LINE characters. Fixing this left as an exercise
#include <stdio.h>
#include <string.h>
#define MAX_LINE 65536
void search_stream(FILE *stream, char stream_name[], char search_for[]);
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: %s <prefix> <files>\n", argv[0]);
return 1;
} if (argc == 2) {
search_stream(stdin, "<stdin>", argv[1]);
} else {
int argument = 2;
while (argument < argc) {
FILE *in = fopen(argv[argument], "r");
if (in == NULL) {
// perror could be used for a better error message here
fprintf(stderr, "%s: open of '%s' failed\n", argv[0], argv[argument]);
return 1;
}
search_stream(in, argv[argument], argv[1]);
argument = argument + 1;
}
}
return 0;
}
void search_stream(FILE *stream, char stream_name[], char search_for[]) {
char line[MAX_LINE];
int line_number = 1;
while (fgets(line, MAX_LINE, stream) != NULL) {
if (strstr(line, search_for) != NULL) {
printf("%s:%d:%s", stream_name, line_number, line);
}
line_number = line_number + 1;
}
}
Simple example of file creation creates file "andrew.txt" containing 1 line ("Andrew rules!")