# Cat in C

Below is a simple example of a C program that opens two files for reading, concatenates their contents, and writes the result to a third file.

```c
#include <stdio.h>
#include <stdlib.h>

int main() {
    // File pointers for input and output files
    FILE *file1, *file2, *outputFile;

    // Open the first file for reading
    file1 = fopen("input1.txt", "r");
    if (file1 == NULL) {
        perror("Error opening file1 for reading");
        exit(EXIT_FAILURE);
    }

    // Open the second file for reading
    file2 = fopen("input2.txt", "r");
    if (file2 == NULL) {
        perror("Error opening file2 for reading");
        fclose(file1);
        exit(EXIT_FAILURE);
    }

    // Open the third file for writing
    outputFile = fopen("output.txt", "w");
    if (outputFile == NULL) {
        perror("Error opening output file for writing");
        fclose(file1);
        fclose(file2);
        exit(EXIT_FAILURE);
    }

    // Concatenate the contents of file1 and file2
    int ch;
    while ((ch = fgetc(file1)) != EOF) {
        fputc(ch, outputFile);
    }

    while ((ch = fgetc(file2)) != EOF) {
        fputc(ch, outputFile);
    }

    // Close all the files
    fclose(file1);
    fclose(file2);
    fclose(outputFile);

    printf("Files concatenated successfully.\n");

    return 0;
}
```

This program assumes that you have two input files named "input1.txt" and "input2.txt" in the same directory as the executable. It creates an output file named "output.txt" containing the concatenated content.

Remember to replace the file names with the actual names of your input files. Additionally, make sure you have the necessary permissions to read from the input files and write to the output file.

Let's go through the details of the provided C program step by step:

1. **Include Headers:**
    
    ```c
    #include <stdio.h>
    #include <stdlib.h>
    ```
    
    These lines include necessary header files. `<stdio.h>` is for input and output operations, and `<stdlib.h>` is for functions involving memory allocation and program control.
    
2. **Main Function:**
    
    ```c
    int main() {
    ```
    
    The program starts execution from the `main` function.
    
3. **File Pointers:**
    
    ```c
    FILE *file1, *file2, *outputFile;
    ```
    
    Three file pointers are declared: `file1` for the first input file, `file2` for the second input file, and `outputFile` for the output file.
    
4. **Open Input Files:**
    
    ```c
    file1 = fopen("input1.txt", "r");
    file2 = fopen("input2.txt", "r");
    ```
    
    The `fopen` function is used to open the input files ("input1.txt" and "input2.txt") for reading (`"r"` mode). If any file fails to open, an error message is printed, and the program exits with a failure status.
    
5. **Open Output File:**
    
    ```c
    outputFile = fopen("output.txt", "w");
    ```
    
    The `fopen` function is used to open the output file ("output.txt") for writing (`"w"` mode). If the output file fails to open, an error message is printed, and the program exits with a failure status.
    
6. **Concatenate Contents:**
    
    ```c
    int ch;
    while ((ch = fgetc(file1)) != EOF) {
        fputc(ch, outputFile);
    }
    while ((ch = fgetc(file2)) != EOF) {
        fputc(ch, outputFile);
    }
    ```
    
    The program uses `fgetc` to read characters from `file1` and `file2` one by one until the end of file (`EOF`) is reached. The characters are then written to `outputFile` using `fputc`. This process effectively concatenates the contents of the two input files into the output file.
    
7. **Close Files:**
    
    ```c
    fclose(file1);
    fclose(file2);
    fclose(outputFile);
    ```
    
    After reading from and writing to files, it's important to close them using `fclose` to release system resources.
    
8. **Print Success Message:**
    
    ```c
    printf("Files concatenated successfully.\n");
    ```
    
    If the program reaches this point, it prints a success message indicating that the files were concatenated successfully.
    
9. **Return:**
    
    ```c
    return 0;
    ```
    
    The `main` function returns 0 to indicate successful execution to the operating system.
    

This program is a simple file concatenation utility. It's important to note that it assumes the existence of input files ("input1.txt" and "input2.txt") and creates an output file ("output.txt") in the same directory as the executable. Also, error handling is included to handle cases where files cannot be opened successfully.

Using `fread` and `fwrite` with a buffer can be more efficient than using `fgetc` and `fputc` when dealing with large amounts of data. Here's the modified program:

```c
#include <stdio.h>
#include <stdlib.h>

#define BUFFER_SIZE 1024

int main() {
    FILE *file1, *file2, *outputFile;
    char buffer[BUFFER_SIZE];
    size_t bytesRead;

    // Open the first file for reading
    file1 = fopen("file1.txt", "rb");
    if (file1 == NULL) {
        perror("Error opening file1.txt");
        return EXIT_FAILURE;
    }

    // Open the second file for reading
    file2 = fopen("file2.txt", "rb");
    if (file2 == NULL) {
        perror("Error opening file2.txt");
        fclose(file1);
        return EXIT_FAILURE;
    }

    // Open a third file for writing
    outputFile = fopen("output.txt", "wb");
    if (outputFile == NULL) {
        perror("Error opening output.txt");
        fclose(file1);
        fclose(file2);
        return EXIT_FAILURE;
    }

    // Copy content from file1 to outputFile using fread/fwrite and a buffer
    while ((bytesRead = fread(buffer, 1, sizeof(buffer), file1)) > 0) {
        fwrite(buffer, 1, bytesRead, outputFile);
    }

    // Copy content from file2 to outputFile using fread/fwrite and a buffer
    while ((bytesRead = fread(buffer, 1, sizeof(buffer), file2)) > 0) {
        fwrite(buffer, 1, bytesRead, outputFile);
    }

    // Close all the files
    fclose(file1);
    fclose(file2);
    fclose(outputFile);

    printf("Files concatenated successfully using fread/fwrite.\n");

    return EXIT_SUCCESS;
}
```

In this version, the program uses a buffer (`char buffer[BUFFER_SIZE]`) to read and write data in chunks, making it more efficient than reading and writing one character at a time. The `BUFFER_SIZE` constant can be adjusted based on the specific needs of your program. Using buffered I/O can significantly reduce the number of system calls and improve performance, especially for large files.

Let's go through the program step by step:

```c
#include <stdio.h>
#include <stdlib.h>

#define BUFFER_SIZE 1024

int main() {
    FILE *file1, *file2, *outputFile;
    char buffer[BUFFER_SIZE];
    size_t bytesRead;
```

* The program starts by including necessary header files (`stdio.h` and `stdlib.h`), defining a constant `BUFFER_SIZE` for the size of the buffer, and declaring variables. Three file pointers (`file1`, `file2`, and `outputFile`) are declared, along with a character array (`buffer`) to store data read from the files. The `bytesRead` variable will be used to keep track of the number of bytes read or written.
    

```c
    // Open the first file for reading
    file1 = fopen("file1.txt", "rb");
    if (file1 == NULL) {
        perror("Error opening file1.txt");
        return EXIT_FAILURE;
    }
```

* The program opens the first file (`file1.txt`) for reading in binary mode (`"rb"`). If the file opening fails, an error message is printed using `perror`, and the program exits with a failure status.
    

```c
    // Open the second file for reading
    file2 = fopen("file2.txt", "rb");
    if (file2 == NULL) {
        perror("Error opening file2.txt");
        fclose(file1);
        return EXIT_FAILURE;
    }
```

* Similarly, the second file (`file2.txt`) is opened for reading in binary mode. If the opening fails, an error message is printed, and the program closes the first file (`file1`) before exiting with a failure status.
    

```c
    // Open a third file for writing
    outputFile = fopen("output.txt", "wb");
    if (outputFile == NULL) {
        perror("Error opening output.txt");
        fclose(file1);
        fclose(file2);
        return EXIT_FAILURE;
    }
```

* The third file (`output.txt`) is opened for writing in binary mode. If the opening fails, an error message is printed, and the program closes the previously opened files (`file1` and `file2`) before exiting with a failure status.
    

```c
    // Copy content from file1 to outputFile using fread/fwrite and a buffer
    while ((bytesRead = fread(buffer, 1, sizeof(buffer), file1)) > 0) {
        fwrite(buffer, 1, bytesRead, outputFile);
    }
```

* The program then enters a loop where it reads data from `file1` using `fread` into the `buffer`. The loop continues as long as there are bytes read (`bytesRead > 0`). The data in the buffer is then written to `outputFile` using `fwrite`. This process is repeated until the entire content of `file1` is read and written.
    

```c
    // Copy content from file2 to outputFile using fread/fwrite and a buffer
    while ((bytesRead = fread(buffer, 1, sizeof(buffer), file2)) > 0) {
        fwrite(buffer, 1, bytesRead, outputFile);
    }
```

* The program repeats a similar process for `file2`, reading its content into the buffer and writing it to `outputFile`. This ensures that the content of both files is concatenated in the `output.txt` file.
    

```c
    // Close all the files
    fclose(file1);
    fclose(file2);
    fclose(outputFile);

    printf("Files concatenated successfully using fread/fwrite.\n");

    return EXIT_SUCCESS;
}
```

* Finally, the program closes all the opened files using `fclose`. If everything is successful, it prints a success message and returns with a success status (`EXIT_SUCCESS`). If there are any errors during file operations, the program exits with a failure status (`EXIT_FAILURE`).
