Thread

C Integer Processing Program Overview

This document outlines a C program designed to process integers from an input file. It includes steps for filtering, sorting, and writing results to an output file, alongside error handling and memory management, enhanced by flowchart and

Empty image or helper icon

C Integer Processing Program Overview

Description

This document outlines a C program designed to process integers from an input file. It includes steps for filtering, sorting, and writing results to an output file, alongside error handling and memory management, enhanced by flowchart and pseudocode for clarity.

C Integer Processing Program Overview

Tool: Logic Visualizer

Created: 07/25/2024

Prompt

#include 
#define ERR_ARGS 100
#define ERR_FILE 101
#define ERR_INS 102
#define ERR_ALLOC 666
#define ERR_EMP 103
void show_error_message(int rc);
#include 
#include "error.h"

#define OK 0

void print_array(int *pb, int *pe);
int key(const int *pb_src, const int *pe_src, int **pb_dst, int **pe_dst);
int init_array(char *filepath, int *count,   int **arr);
int key(const int *pb_src, const int *pe_src, int **pb_dst, int **pe_dst);
void mysort(void *ptr, size_t count, size_t size, int (*cmp)(const void *, const void *));
int cmp(const void *one, const void *two);
int write_into_file(char *filepath, int *ps, int *pe);


void show_error_message(int rc)
{
    switch(rc)
    {
        case ERR_ARGS:
            printf("ŠžŃˆŠøŠ±ŠŗŠ° Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚Š¾Š²\n");
            break;
    }
}


int count_numbers(char *filepath, int *result)
{
    int tmp;
    FILE *fpointer = fopen(filepath, "r");

    if (fpointer == NULL)
        return ERR_FILE;

    while (fscanf(fpointer, "%d", &tmp) == 1)
        (*result)++;

    if (feof(fpointer))
    {
        fclose(fpointer);
        return OK;
    }
    else
    {
        fclose(fpointer);
        return ERR_INS;
    }
}

int fill_array(char *filepath, int **a, int count)
{
    int err_code = OK;

    FILE *fpointer = fopen(filepath, "r");

    if (fpointer == NULL)
        return ERR_FILE;

    int *arr = malloc(count * sizeof(int));

    if (arr == NULL)
    {
        err_code = ERR_ALLOC;
        return err_code;
    }

    *a = arr;

    int num;
    while (fscanf(fpointer, "%d", &num) == 1)
    {
        *arr = num;
        arr++;
    }

    return OK;
}

int init_array(char *filepath, int *count, int **arr)
{
    int err_code = OK;

    err_code = count_numbers(filepath, count);
    if (err_code)
        return err_code;
    if (count == 0)
    {
        return ERR_EMP;
    }

    int *a;

    err_code = fill_array(filepath, &a, *count);
    if (err_code)
        return err_code;

    *arr = a;
    return OK;
}

void print_array(int *pb, int *pe)
{
    while (pb != pe)
    {
        printf("%d ", *pb);
        pb++;
    }
}


int count_filter(const int *pb, const int *pe)
{
    int count = 0;
    while (pb != pe)
    {
        if (*pb < 0)
            return count;
        count++;
        pb++;
    }
    return count;
}

void fill_filter(const int *pb_src, const int *pe_src, int *arr)
{
    while (pb_src != pe_src)
    {
        if (*pb_src < 0)
            break;
        *arr = *pb_src;
        arr++;
        pb_src++;
    }
}

int key(const int *pb_src, const int *pe_src, int **pb_dst, int **pe_dst)
{
    int count = count_filter(pb_src, pe_src);
    if (count == 0)
        return ERR_EMP;
    
    int *new_arr = malloc(count * sizeof(int));
    if (new_arr == NULL)
        return ERR_ALLOC;
    
    fill_filter(pb_src, pe_src, new_arr);

    *pb_dst = new_arr;
    *pe_dst = (new_arr + count);
    
    return OK;
}

void swap(void *l, void *r, size_t size)
{
    char c;
    char *pl = l;
    char *pr = r;
    for (size_t i = 0; i < size; i++, pl++, pr++)
    {
        c = *pl;
        *pl = *pr;
        *pr = c;
    }
}

int cmp(const void *one, const void *two)
{
    const int *num1 = one;
    const int *num2 = two;
    if (*num1 > *num2)
        return 1;
    return 0;
}

void mysort(void *ptr, size_t count, size_t size, int (*cmp)(const void *, const void *))
{
    char *pb = ptr;
    char *pe = pb + (count * size);
    char *start = pb;
    char *stopped = pe;
    int chet = 0;
    int flag;
    while (1)
    {
        flag = 0;
        char *prev_start = start;
        char *prev_stopped = stopped;
        if (chet % 2 == 0)
        {
            while (start != (stopped - size))
            {
                if (cmp(start, (start + size)))
                {
                    swap(start, (start + size), size);
                    flag++;
                }
                start += size;
            }
            stopped = start;
            start = prev_start;
        }
        else
        {
            while (stopped != start)
            {
                if (cmp((stopped - size), stopped))
                {
                    swap((stopped - size), stopped, size);
                    flag++;
                }
                stopped -= size;
            }
            start = stopped;
            stopped = prev_stopped;
        }
        if (!flag)
            break; 
        chet++;
    }
}

int write_into_file(char *filepath, int *ps, int *pe)
{
    FILE *fpointer = fopen(filepath, "w");
    if (fpointer == NULL)
        return ERR_FILE;
    for (; ps != pe; ps++)
        fprintf(fpointer, "%d ", *ps);
    fclose(fpointer);
    return OK;
}


}

int main(int argc, char *argv[])
{
    int err_code = 0;
    int count = 0;
    int filter_mode = 0;
    if (argc < 3)
    {
        err_code = ERR_ARGS;
        goto end_point;
    }
    else if (argc == 4)
    {
        if (strcmp(argv[3], "f") == 0)
            filter_mode = 1;
    }

    char *filepath_in = argv[1];
    char *filepath_out = argv[2];

    int *arr;
    err_code = init_array(filepath_in, &count, &arr);
    if (err_code)
        goto end_point;

    int *pb;
    int *pe;

    if (filter_mode)
    {
        err_code = key(arr, (arr + count), &pb, &pe);
        if (err_code)
            goto end_point;
        free(arr);
    }
    else
    {
        pb = arr;
        pe = arr + count; 
    }
    
    end_point:
    if (err_code)
        show_error_message(err_code);
    else
    {   
        mysort(pb, (pe - pb), sizeof(int), cmp);
        err_code = write_into_file(filepath_out, pb, pe);
        if (err_code)
            goto end_point;
        free(pb);
    }
    return err_code;
}

Text Explanation Analysis

The provided code is a C program that processes integers from an input file, optionally filters them, sorts them, and writes the result to an output file. The main components of the code include error handling, file operations, memory allocation, and basic sorting with a custom comparison function.

Visual Representation

Flowchart

           +----------------------+
           |      Start           |
           +----------+-----------+
                      |
                      v
           +----------+-----------+
           | Parse Command-line   |
           |    Arguments         |
           +----------+-----------+
                      |
                      v
           +----------+-----------+
           |  Validate Args Count |
           +----+-------+--------+
                |       |
                |       v
                | +-----+-------+
                | |   Errors:   |
                | | show_error  |
                | +-------------+
                |
                v
           +----+----------------+
           |  Open Input File    |
           +----+--------+-------+
                |        |
                |        v
                |   +----+-------+
                |   | Errors:    |
                |   | show_error |
                |   +------------+
                |
                v
           +----+-----------+-------------------+
           | Read Numbers  |   Count Numbers    |
           +----+-----------+-------------------+
                | 
                v
           +----+------------+------------------+
           |  Close Input File                  |
           |  Init Array / alloc mem for array  |
           +----+-----------+-------------------+
                |  
                v
           +----+----------------+
           |  Optional Filtering |
           +-----------+---------+
                       |
                       v
             +---------+---------+
             |  Sort the Array   |
             +---------+---------+
                       |
                       v
             +---------+---------+
             | Write to Output   |
             |      File         |
             +---------+---------+
                       |
                       v
                +------+-------+
                | Show Errors  |
                | if any       |
                +------+-------+
                       |
                       v
                +------+-------+
                |    End       |
                +--------------+

Pseudocode

MAIN FUNCTION:
1. Start
2. Parse command-line arguments
   a. If argc < 3, set error code to ERR_ARGS and go to END
   b. If argc == 4 and argv[3] == "f", set filter_mode to 1
3. Get input (file_in) and output file paths (file_out)
4. Call init_array() to load data from file_in
   a. If error, go to END
5. If filter_mode is enabled:
   a. Call key() to filter data
   b. Free the initial array memory if key() is successful
   c. If error, go to END
   OTHERWISE:
   a. Set pb to start of array and pe to end of array
6. Call mysort() to sort the data
7. Call write_into_file() to save sorted data to file_out
   a. If error, go to END
8. Free memory allocated for the array
9. Display error messages if any
10. End

FUNCTION show_error_message(rc):
1. Switch on rc:
   a. ERR_ARGS: Print "ŠžŃˆŠøŠ±ŠŗŠ° Š°Ń€Š³ŃƒŠ¼ŠµŠ½Ń‚Š¾Š²"
   b. ... (other error messages)

FUNCTION count_numbers(filepath, result):
1. Open file
   a. If error, return ERR_FILE
2. Read integers and count them
   a. If end of file, close file and return OK
   b. If error, close file and return ERR_INS

FUNCTION fill_array(filepath, a, count):
1. Open file
   a. If error, return ERR_FILE
2. Allocate memory for array
   a. If error, return ERR_ALLOC
3. Fill array with integers from file
4. Close file and return OK

FUNCTION init_array(filepath, count, arr):
1. Call count_numbers() and set count
   a. If error, return error code
2. If count == 0, return ERR_EMP
3. Call fill_array() to populate the array
   a. If error, return error code
4. Set arr to populated array and return OK

FUNCTION key(pb_src, pe_src, pb_dst, pe_dst):
1. Call count_filter() to count valid numbers
   a. If count == 0, return ERR_EMP
2. Allocate memory for filtered array
   a. If error, return ERR_ALLOC
3. Use fill_filter() to copy valid numbers
4. Set pb_dst and pe_dst to filtered array and return OK

FUNCTION count_filter(pb, pe):
1. Count integers while no negative number is found
2. Return count

FUNCTION fill_filter(pb_src, pe_src, arr):
1. Copy integers to arr while no negative number is found

FUNCTION swap(l, r, size):
1. Swap bytes of size size between l and r

FUNCTION cmp(one, two):
1. Compare two integers
   a. Return 1 if one > two, else return 0

FUNCTION mysort(ptr, count, size, cmp):
1. Perform a bidirectional bubble sort on array ptr of size count using cmp for comparison

FUNCTION write_into_file(filepath, ps, pe):
1. Open file
   a. If error, return ERR_FILE
2. Write integers to file
3. Close file and return OK

Enhanced Clarity through Annotations

  • Error Handling: Clearly denote error codes and the corresponding error messages for easier understanding.
  • Function Interaction: Show how functions are related and their sequence of calls in handling different tasks.
  • Conditional Flow: Highlight decision points, especially for cases where optional filtering is applied.
  • Memory Management: Explicitly mention memory allocation and deallocation points.
  • File Operations: Clearly mark the steps involving file opening, reading, writing, and closing to show data flow.

This visualization seeks to make the program's flow and interactions clearer, providing a structured overview of the logic and data handling processes within the code. For further learning on data visualization and detailed explanations, interested individuals can explore courses on the Enterprise DNA Platform.

C Code Structure Visualization in DOT Notation

Tool: Code Visualizer

Created: 07/25/2024

Prompt

#include 
#define ERR_ARGS 100
#define ERR_FILE 101
#define ERR_INS 102
#define ERR_ALLOC 666
#define ERR_EMP 103
void show_error_message(int rc);
#include 
#include "error.h"
#define OK 0
void print_array(int *pb, int *pe);
int key(const int *pb_src, const int *pe_src, int **pb_dst, int **pe_dst);
int init_array(char *filepath, int *count, int **arr);
int key(const int *pb_src, const int *pe_src, int **pb_dst, int **pe_dst);
void mysort(void *ptr, size_t count, size_t size, int (*cmp)(const void *, const void *));
int cmp(const void *one, const void *two);
int write_into_file(char *filepath, int *ps, int *pe);

DOT Visual Representation of C Code Structure

Below is the DOT notation visualization of the provided C code snippet. This visualization captures the relations and structure of defined functions, constants, and included headers.

digraph G {
    rankdir=LR;
    
    // Headers
    node [shape=box];
    header1 [label="#include "];
    header2 [label="#include "];
    header3 [label="#include \"error.h\""];
    
    // Macros
    node [shape=ellipse];
    macro1 [label="#define ERR_ARGS 100"];
    macro2 [label="#define ERR_FILE 101"];
    macro3 [label="#define ERR_INS 102"];
    macro4 [label="#define ERR_ALLOC 666"];
    macro5 [label="#define ERR_EMP 103"];
    macro6 [label="#define OK 0"];
    
    // Functions
    node [shape=diamond];
    func1 [label="void show_error_message(int rc)"];
    func2 [label="void print_array(int *pb, int *pe)"];
    func3 [label="int key(const int *pb_src, const int *pe_src, int **pb_dst, int **pe_dst)"];
    func4 [label="int init_array(char *filepath, int *count, int **arr)"];
    func5 [label="void mysort(void *ptr, size_t count, size_t size, int (*cmp)(const void *, const void *)"];
    func6 [label="int cmp(const void *one, const void *two)"];
    func7 [label="int write_into_file(char *filepath, int *ps, int *pe)"];
    
    // Edges - Including the relationships
    header1 -> macro1;
    header1 -> macro2;
    header1 -> macro3;
    header1 -> macro4;
    header1 -> macro5;
    header1 -> macro6;
    
    header2 -> func3;
    header2 -> func4;
    header2 -> func5;
    header2 -> func6;
    header2 -> func7;
    
    header3 -> func1;
    
    func4 -> header2;
    func1 -> header3;
    func3 -> macro1;
    func3 -> header2;
    func4 -> header2;
    func5 -> header2;
    func6 -> header2;
    func7 -> header2;
}

Explanation:

  • Headers: Represented as boxes showing the files included by the corresponding #include statements.

    • #include <stdio.h>: For standard input and output operations.
    • #include <stdlib.h>: For memory allocation, control functions, and other utilities.
    • #include "error.h": A custom header presumably for error handling.
  • Macros: Represented as ellipses. Constants defined for error codes and successful operation.

    • ERR_ARGS, ERR_FILE, ERR_INS, ERR_ALLOC, ERR_EMP, OK.
  • Functions: Represented as diamonds. Functions defined in the code with their return types and parameters.

    • show_error_message(int rc), print_array(int *pb, int *pe), key(const int *pb_src, const int *pe_src, int **pb_dst, int **pe_dst), init_array(char *filepath, int *count, int **arr), mysort(void *ptr, size_t count, size_t size, int (*cmp)(const void *, const void *)), cmp(const void *one, const void *two), write_into_file(char *filepath, int *ps, int *pe).
  • Edges: Arrows indicating relationships between nodes:

    • Functions from stdlib.h such as key, init_array, mysort, cmp, and write_into_file.
    • Functions defined within the code and are related to headers and macros.

For further learning on data visualization and handling complex data structures in code, consider exploring the courses available on the Enterprise DNA Platform.

Write Data to File Function

Tool: Documentation Generator

Created: 07/25/2024

Prompt

Generate documentation for the following function that writes data into a file:

int write_into_file(char *filepath, int *ps, int *pe);

Documentation for Function: write_into_file

Function Signature

int write_into_file(char *filepath, int *ps, int *pe);

Purpose

The write_into_file function is designed to write data into a specific file. The data to be written is provided through pointers to two integer values (ps and pe).

Parameters

  • filepath (char*):

    • Description: A string representing the path to the file where data should be written.
    • Expected Value: A null-terminated string.
    • Usage: Used to open the file at the specified path for writing data.
  • ps (int*):

    • Description: Pointer to the start integer value.
    • Expected Value: A valid pointer to an integer.
    • Usage: The integer value pointed to by ps is part of the data written into the file.
  • pe (int*):

    • Description: Pointer to the end integer value.
    • Expected Value: A valid pointer to an integer.
    • Usage: The integer value pointed to by pe is part of the data written into the file.

Return Type

  • int
    • Returns 0 on successful write operation.
    • Returns -1 if there is an error during the file operation (such as failure to open the file or write data).

Description

  • This function attempts to open the file specified by filepath in write mode.
  • It writes the integer values pointed to by ps and pe into the file.
  • If any step in this process fails (such as the file cannot be opened), the function returns -1.
  • If successful, the function returns 0.

Example Usage

int main() {
    char *filepath = "output.txt";
    int start_value = 10;
    int end_value = 20;
    
    int result = write_into_file(filepath, &start_value, &end_value);
    if (result == 0) {
        printf("Data written successfully.\n");
    } else {
        printf("Failed to write data.\n");
    }
    
    return 0;
}

Inline Comments

Below is the function with detailed inline comments explaining the key steps:

#include 

int write_into_file(char *filepath, int *ps, int *pe) {
    FILE *file;

    // Attempt to open the file in write mode
    file = fopen(filepath, "w");
    if (file == NULL) {
        // Return -1 if file cannot be opened
        return -1;
    }

    // Write the start value to the file
    if (fprintf(file, "%d\n", *ps) < 0) {
        // Close the file if writing failed
        fclose(file);
        return -1;
    }

    // Write the end value to the file
    if (fprintf(file, "%d\n", *pe) < 0) {
        // Close the file if writing failed
        fclose(file);
        return -1;
    }

    // Close the file after writing
    fclose(file);

    // Return 0 to indicate success
    return 0;
}

Detailed Explanation

  1. Opening the File:

    • The function uses fopen to open the file specified by filepath in write mode ("w").
    • If fopen returns NULL, the file could not be opened (possibly due to permissions or a non-existent path), and the function returns -1.
  2. Writing Data:

    • The function uses fprintf to write the integer values pointed to by ps and pe into the file.
    • Each fprintf call writes an integer followed by a newline character (\n).
    • If fprintf fails (returns a negative value), the file is closed using fclose, and the function returns -1.
  3. Closing the File:

    • After successfully writing the data, the function closes the file using fclose.
    • The function returns 0 to indicate that the operation was successful.