c programming reading multiple files technique - c

I am curious what is the best way to open multiple files. I know you use a combination of FILE *inputfp1; and inputfp1 = fopen(argv[1], "r"); then check for errors. I would like to know the best way to do this.
Is it best to open and close one file at a time like this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char **argv) {
char line[80] = {0};
FILE *inputfp1;
//input = fopen("myfile.txt", "r");
inputfp1 = fopen(argv[1], "r"); //Open file for read.
if (inputfp1 == NULL)
{
printf("Error opening file %s!",argv[1]); //Program prints error message and closes if file is not found
exit(0);
}
if( argc == 7 )
{
/*printf("The first argument supplied is %s\n", argv[1]);
printf("The second argument supplied is %s\n", argv[2]);
printf("The third argument supplied is %s\n", argv[3]);
printf("The first argument supplied is %s\n", argv[4]);
printf("The second argument supplied is %s\n", argv[5]);
printf("The third argument supplied is %s\n", argv[6]);
printf("The third argument supplied is %s\n", argv[7]);*/
}
else if( argc > 7 )
{
printf("Too many arguments supplied.\n");
exit( 1 );
}
else
{
printf("Not enough arguments supplied. \n");
exit( 1 );
}
//Unique behavior on file1
while(fgets(line, 80, inputfp1) != NULL)
{
//do work on file1
}
fclose(inputfp1);
inputfp1 = fopen(argv[2], "r"); //Open file for read.
if (inputfp1 == NULL)
{
printf("Error opening file %s!",argv[1]); //Program prints error message and closes if file is not found
exit(0);
}
//Unique behavior on file2
while(fgets(line, 80, inputfp1) != NULL)
{
//do work on file2
}
fclose(inputfp1);
return 0;
}
Is it better to create all the file pointers and open all the files at once like this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char **argv) {
char line[80] = {0};
FILE *inputfp1;
FILE *inputfp2;
FILE *inputfp3;
FILE *inputfp4;
FILE *inputfp5;
FILE *inputfp6;
//input = fopen("myfile.txt", "r");
inputfp1 = fopen(argv[1], "r"); //Open file for read.
inputfp2 = fopen(argv[2], "r"); //Open file for read.
inputfp3 = fopen(argv[3], "r"); //Open file for read.
inputfp4 = fopen(argv[4], "r"); //Open file for read.
inputfp5 = fopen(argv[5], "r"); //Open file for read.
inputfp6 = fopen(argv[6], "r"); //Open file for read.
if (inputfp1 == NULL)
{
printf("Error opening file %s!",argv[1]); //Program prints error message and closes if file is not found
exit(0);
}
//The rest of error checking.
if( argc == 7 )
{
/*printf("The first argument supplied is %s\n", argv[1]);
printf("The second argument supplied is %s\n", argv[2]);
printf("The third argument supplied is %s\n", argv[3]);
printf("The first argument supplied is %s\n", argv[4]);
printf("The second argument supplied is %s\n", argv[5]);
printf("The third argument supplied is %s\n", argv[6]);
printf("The third argument supplied is %s\n", argv[7]);*/
}
else if( argc > 7 )
{
printf("Too many arguments supplied.\n");
exit( 1 );
}
else
{
printf("Not enough arguments supplied. \n");
exit( 1 );
}
//Unique behavior on file1
while(fgets(line, 80, inputfp1) != NULL)
{
//do work on file1
}
fclose(inputfp1);
//Unique behavior on file2
while(fgets(line, 80, inputfp2) != NULL)
{
//do work on file2
}
fclose(inputfp2);
//The rest of reading and closing files.
return 0;
}
Are there any better ways I missed?

A good way of doing this would be putting all your file pointers in an array:
FILE *inputfp[6];
for(int i=0;i<6;i++)
{
inputfp[i] = fopen(argv[i+1], "r"); //Open file for read.
if (inputfp[i] == NULL)
{
printf("Error opening file %s!",argv[i+1]); //Program prints error message and closes if file is not found
exit(0);
}
}

I'd do it the first way, but use a loop:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char **argv) {
char line[80] = {0};
FILE *inputfp1;
if( argc == 7 )
{
/*printf("The first argument supplied is %s\n", argv[1]);
printf("The second argument supplied is %s\n", argv[2]);
printf("The third argument supplied is %s\n", argv[3]);
printf("The first argument supplied is %s\n", argv[4]);
printf("The second argument supplied is %s\n", argv[5]);
printf("The third argument supplied is %s\n", argv[6]);
printf("The third argument supplied is %s\n", argv[7]);*/
}
else if( argc > 7 )
{
printf("Too many arguments supplied.\n");
exit( 1 );
}
else
{
printf("Not enough arguments supplied. \n");
exit( 1 );
}
for (int i = 1; i < argc; ++i)
{
inputfp1 = fopen(argv[i], "r"); //Open file for read.
if (inputfp1 == NULL)
{
printf("Error opening file %s!",argv[i]); //Program prints error message and closes if file is not found
exit(0);
}
while(fgets(line, 80, inputfp1) != NULL)
{
//do work
}
fclose(inputfp1);
}
return 0;
}

Related

C programming, copying from one file to another using command line arguments

This is my code
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc < 4) {
printf("Missing arguments\n");
return -1;
}
// Check if buffer is valid before reading anything
int bufferSize = atoi(argv[3]);
if (!bufferSize || bufferSize < 1) {
printf("Invalid buffer size\n");
return -1;
}
printf("*** Copying from '%s' to '%s' (Buffer size: %dB) ***\n",
argv[1], argv[2], bufferSize);
// READ SOURCE FILE
FILE *inputFile = fopen(argv[1], "r");
if (!inputFile) {
printf("Error opening source file\n");
return -1;
}
// READ DESTINATION FILE
FILE *outputFile = fopen(argv[2], "w");
if (!outputFile) {
printf("Error opening destination file\n");
return -1;
}
int buffer[bufferSize];
int bytes;
do {
bytes = fread(buffer, 1, bufferSize, inputFile);
if (fwrite(buffer, 1, bytes, outputFile) != bytes) {
printf("Error writing into destination file\n");
return -1;
}
} while (bytes > 0);
fclose(inputFile);
fclose(outputFile);
return 0;
}
But when I try to exe the file it doesn't work. What could be the problem?
Here's the command line:
/Users/jurajc/Documents/Program/C/L1\ 1/C_program/c_program file.txt fileCopy.txt 512
*** Copying from 'file.txt' to 'fileCopy.txt' (Buffer size: 512B) ***
Error opening source file
The input file file.txt cannot be opened: either because it is not present in the current directory or because you do not have read access to it.
You should output more informative error messages. Note also these problems:
if (!bufferSize || bufferSize < 1) is a redundant test. if (bufferSize < 1) is sufficient.
the error messages should be output to stderr
the files should be open in binary mode to reliably copy all file types on legacy systems.
the read/write loop is incorrect: you should stop when fread returns 0 before attempting to write 0 elements to the output file.
Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc < 4) {
fprintf(stderr, "Missing arguments\n");
return -1;
}
// Check if buffer is valid before reading anything
int bufferSize = atoi(argv[3]);
if (bufferSize < 1) {
fprintf(stderr, "Invalid buffer size: %s\n", argv[3]);
return -1;
}
printf("*** Copying from '%s' to '%s' (Buffer size: %dB) ***\n",
argv[1], argv[2], bufferSize);
// READ SOURCE FILE
FILE *inputFile = fopen(argv[1], "rb");
if (!inputFile) {
fprintf(stderr, "Error opening source file %s: %s\n",
argv[1], strerror(errno));
return -1;
}
// READ DESTINATION FILE
FILE *outputFile = fopen(argv[2], "wb");
if (!outputFile) {
fprintf(stderr, "Error opening destination file %s: %s\n",
argv[2], strerror(errno));
return -1;
}
int buffer[bufferSize];
int bytes;
while ((bytes = fread(buffer, 1, bufferSize, inputFile)) != 0) {
if (fwrite(buffer, 1, bytes, outputFile) != bytes) {
fprintf(stderr, "Error writing into destination file: %s\n", strerror(errno));
return -1;
}
}
fclose(inputFile);
fclose(outputFile);
return 0;
}

I am trying to print a txt file and it doesn't work in C homework

I'm writing code that's supposed to verify that a .txt file is a certain format.
I wrote my code as I saw in a tutorial and in the website
and for some reason my program doesn't even print my file.
Can you tell me what I'm doing wrong?
The code will do something far more complex, but I'm still trying to work on my basics.
Here's my code so far:
int main(int argc, char *argv[]) {
/* argv[0] = name of my running file
* argv[1] = the first file that i receive
*/
define MAXBUFLEN 4096
char source[MAXBUFLEN + 1];
int badReturnValue = 1;
char *error = "Error! trying to open the file ";
if (argc != 2) {
printf("please supply a file \n");
return badReturnValue;
}
char *fileName = argv[1];
FILE *fp = fopen(argv[1], "r"); /* "r" = open for reading */
if (fp != NULL) {
size_t newLen = fread(&source, sizeof(char), MAXBUFLEN, fp);
if (ferror(fp) != 0) {
printf("%s %s", error, fileName);
return badReturnValue;
}
int symbol;
while ((symbol = getc(fp)) != EOF) {
putchar(symbol);
}
printf("finish");
fclose(fp);
}
else {
printf("%s %s", error, fileName);
return badReturnValue;
}
}
I think you need a bit more explanations:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
// there might be a macro BUFLEN defined in stdio
// which size is optimized for reading in chunks.
// Test if avaiable otherwise define it
#ifndef BUFLEN
# define BUFLEN 4096
#endif
int main(int argc, char *argv[])
{
char source[BUFLEN];
char *filename;
FILE *fp;
size_t fpread, written;
char c;
int ret_fclose;
if (argc != 2) {
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(EXIT_FAILURE);
}
// reset errno, just in case
errno = 0;
// work on copy
filename = malloc(strlen(argv[1]) + 1);
if (filename == NULL) {
fprintf(stderr, "Allocating %zu bytes failed\n", strlen(argv[1]) + 1);
exit(EXIT_FAILURE);
}
filename = strcpy(filename, argv[1]);
// try to open the file at 'filename'
fp = fopen(filename, "r");
if (fp == NULL) {
fprintf(stderr, "Opening file \"%s\" filename failed\n", filename);
// errno might got set to something usable, check and print
if (errno != 0) {
fprintf(stderr, "Error: %s\n", strerror(errno));
}
exit(EXIT_FAILURE);
}
// You have two options here. One is to read in chunks of MAXBUFLEN
while ((fpread = fread(&source, 1, BUFLEN, fp)) > 0) {
// Do something with the stuff we read into "source"
// we do nothing with it here, we just write to stdout
written = fwrite(&source, 1, fpread, stdout);
// you can use 'written' for error check when writing to an actual file
// but it is unlikely (but not impossible!) with stdout
// test if we wrote what we read
if ((fpread - written) != 0) {
fprintf(stderr, "We did not write what we read. Diff: %d\n",
(int) (fpread - written));
}
}
// fread() does not distinguish between EOF and error, we have to check by hand
if (feof(fp)) {
// we have read all, exit
puts("\n\n\tfinish\n");
// No, wait, we want to do it again in a different way, so: no exit
// exit(EXIT_SUCCESS);
} else {
// some error may have occured, check
if (ferror(fp)) {
fprintf(stderr, "Something bad happend while reading \"%s\"\n", filename);
if (errno != 0) {
fprintf(stderr, "Error: %s\n", strerror(errno));
}
exit(EXIT_FAILURE);
}
}
// the other way is to read it byte by byte
// reset the filepointers/errors et al.
rewind(fp);
// rewind() should have reseted errno, but better be safe than sorry
errno = 0;
printf("\n\n\tread and print \"%s\" again\n\n\n\n", filename);
// read one byte and print it until end of file
while ((c = fgetc(fp)) != EOF) {
// just print. Gathering them into "source" is left as an exercise
fputc(c, stdout);
}
// clean up
errno = 0;
ret_fclose = fclose(fp);
// even fclose() might fail
if (ret_fclose == EOF) {
fprintf(stderr, "Something bad happend while closing \"%s\"\n", filename);
if (errno != 0) {
fprintf(stderr, "Error: %s\n", strerror(errno));
}
exit(EXIT_FAILURE);
}
// The macros EXIT_FAILURE and EXIT_SUCCESS are set to the correct values for
// the OS to tell it if we had an eror or not.
// Using exit() is noot necessary here but there exits teh function atexit()
// that runs a given function (e.g: clean up, safe content etc.) when called
exit(EXIT_SUCCESS);
}
You read from the file twice but only print once.
If the file is to small the first reading will read all of the contents, and the second reading will not produce anything so you don't print anything.
I believe you have to reset the pointer after using fread.
Try fseek(fp, SEEK_SET, 0) to reset the pointer to the beginning of the file. Then print the file.

C assign string from argv[] to char array

I have the following code which reads an file name from the command line and opens this file:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv){
FILE *datei;
char filename[255];
//filename = argv[1];
//datei=fopen(filename, "r");
datei=fopen(argv[1], "r");
if(datei != NULL)
printf("File opened");
else{
printf("Fehler beim öffnen von %s\n", filename);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
This example works, but I want to write the string from the command line to the char array and pass that char array to to fopen(), but i get the compiler error
Error: assignment to expression with array type filename = argv[1];
What does this error mean and what can I do to fix it?
You must copy the string into the char array, this cannot be done with a simple assignment.
The simplistic answer is strcpy(filename, argv[1]);.
There is a big problem with this method: the command line parameter might be longer than the filename array, leading to a buffer overflow.
The correct answer therefore:
if (argc < 2) {
printf("missing filename\n");
exit(1);
}
if (strlen(argv[1]) >= sizeof(filename)) {
printf("filename too long: %s\n", argv[1]);
exit(1);
}
strcpy(filename, argv[1]);
...
You might want to output the error messages to stderr.
As a side note, you probably want to choose English or German, but not use both at the same time ;-)
An even simpler solution is to just keep a copy of the pointer argv[1] in a char *filename. Unless you modify it yourself, a very bad idea, its contents will not change for the duration of the program execution.
Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
FILE *datei;
char *filename;
if (argc < 2) {
fprintf(stderr, "Fehlendes Dateiname-Befehlszeilenargument\n");
return EXIT_FAILURE;
}
filename = argv[1];
datei = fopen(filename, "r");
if (datei != NULL) {
printf("Datei erfolgreich geöffnet\n");
} else {
fprintf(stderr, "Fehler beim öffnen von %s: %s\n",
filename, strerror(errno));
return EXIT_FAILURE;
}
// ...
fclose(datei);
return EXIT_SUCCESS;
}

How to Write Differences in Two Text Files to Another Text File in C?

I'd like to write a program that compares two files and writes every byte in file one that is different from file two into a third file. I want to compare the files byte by byte and write any differing single bytes to the third file. I'm not very familiar with file I/O. Can someone give me an example program that accomplishes this task?
This is what I have so far:
int main(int argc, char *argv[]) {
int file1, file2, file1size, file2size;
// int difference1, difference2;
char buf;
if (argc != 3){
fprintf(stderr, "Usage %s <file1> <file2>", argv[0]);
exit(1);
}
if ((file1 = open(argv[1], 0400)) < 0) { //read permission for user on file source
fprintf(stderr, "Can't open source");
exit(1);
}
if ((file2 = open(argv[2], 0400)) < 0) { //read permission for user on file source
fprintf(stderr, "Can't open source");
exit(1);
}
file1size = lseek(file1, (off_t) 0, SEEK_END);
printf("File 1's size is %d\n", file1size);
file2size = lseek(file2, (off_t) 0, SEEK_END);
printf("File 2's size is %d\n", file2size);
}
I'm not sure how to compare file1 and file2's bytes and then write the differences to another file.
This is close to what you are looking for.
#include <stdio.h>
int main(int argc, char *argv[]) {
FILE *file1 = fopen(argv[1], "r");
FILE *file2 = fopen(argv[2], "r");
int i;
for(i = 0; !feof(file1) || !feof(file2); i++) {
int byte1 = getc(file1);
int byte2 = getc(file2);
if(byte1 != byte2) {
printf("%d %d %d\n", i, byte1, byte2);
}
}
return 0;
}
It takes the two files as command line arguments and compares the two byte-by-byte. If two bytes are different, it printf the character #, and the ASCII values of the two characters. -1 means EOF was already reached.
You'll have to (understand and) adapt this to the output format you want. (I'm assuming this is homework.)
feof tests for end-of-file.
getc gets the next character (byte) from the file. It is -1 if the end of the file has been reached.
And you seem already to know what printf does.
This does what you want, compiles, and runs,
#include <stdio.h>
int main(int argc, char *argv[])
{
int offset;
int argi=1;
int ch1, ch2;
FILE *fh1, *fh2, *fh3=stdout;
FILE *fh4=stdout;
if( argc<3 ) {
printf("usage: diff <file> <file> { <outfile> }\n"); return(1);
}
if(argi<argc) {
if(!(fh1 = fopen(argv[argi], "r"))) {
printf("cannot open %s\n",argv[argi]); return(2);
}
}
if(++argi<argc) {
if(!(fh2 = fopen(argv[argi], "r"))) {
printf("cannot open %s\n",argv[argi]); return(3);
}
}
if(++argi<argc) {
if(!(fh3 = fopen(argv[argi], "w+"))) {
printf("cannot open %s\n",argv[argi]); return(4);
}
}
if(++argi<argc) {
//duplicate output to a second file?
if(!(fh4 = fopen(argv[argi], "r"))) {
printf("cannot open %s\n",argv[argi]); return(3);
}
}
for(offset = 0; (!feof(fh1)) && (!feof(fh2)); offset++)
{
ch1=ch2='-';
if(!feof(fh1)) ch1 = getc(fh1);
if(!feof(fh2)) ch2 = getc(fh2);
if(ch1 != ch2) {
fprintf(fh3,"%d:%c %c\n", offset, ch1, ch2);
//additional file here
}
else {
fprintf(fh3,"%c\n", ch1);
//additional file here
}
}
return 0;
}
More typically, you would read entire lines using fgets, and strcmp to compare the lines. Here is how,
char str1[1024], str2[1024];
...
for(offset = 0; (!feof(fh1)) && (!feof(fh2)); offset++)
{
strcpy(str1,"-");strcpy(str2,"-");
if(!feof(fh1)) fgets(str1,sizeof(str1),fh1);
if(!feof(fh2)) fgets(str2,sizeof(str1),fh2);
if(strcmp(str1,str2)!=0)
fprintf(fh3,"%d:%s %s", offset, str1, str2);
else
fprintf(fh3,"%c", str1);
}

Running a FIFO Simulation

I am trying to run a simulation program to test the FIFO algorithm, however my program is just crashing. this is the main, other functions not shown. Can anyone spot for me the problem.Am not so familiar with using the main Argument[ int main(int argc, char *argv[])]
I have the testing files in a folder
int main(int argc, char *argv[])
{
FILE *stream;
if (argc != 3)
{
printf("The format is: pager file_name memory_size.\n");
//exit(1);
}
printf("File used %s, resident set size %d\n", argv[1], atoi(argv[2]));
if ((stream = fopen(argv[1], "r")) == NULL)
{
perror("File open failed");
//exit(1);
}
mem_size = atoi(argv[2]);
start_simulation(stream);
fclose(stream);
system("pause");
}
Uncomment the calls to exit.
if (argc != 3) {
// insufficient arguments passed..print error and exit.
printf("The format is: pager file_name memory_size.\n");
exit(1);
}
In your case (exit commented) if you don't provide command line arguments, argv[1] will be NULL and this can cause crash when used in fopen

Resources