how to use values from command arguments in c

2

I have a task to write a code for this instructions but when I run the program I get this error :

Exception thrown at 0x7BCAF338 (ucrtbased.dll) in HW5.exe: 0xC0000005: Access violation reading location 0x00207265. occurred

Autos:

book_name 0x0136f71c "Hub ultra " char *

head  0x00207265 {name=0x00207265 <Error reading characters of string.> copies=??? next=??? } book *

head->name    0x00207265 <Error reading characters of string.>    char[200]

Why ? How can I solve this problem ? What is the mistake in my program ?

The structure of a media component:

// define struct
typedef struct hw_component
{
char name[NAME_LENGTH];
int copies;
struct hw_component *next;
} HW_component;

Name: indicates the name of a media component.

Copies: indicates the number of the components.

You should define maximum name length as follows.

#define NAME_LENGTH 200

Now, instead of showing the menu and taking the orders from user, we will use files. You will see the list of orders in the text file actions.txt. Components inventory will appear in hw_components.txt file. Please print the updated inventory list in updated_components.txt file.

Your program should not have any interface with users. Your input and output should be only fromand into text files (except for printing in case of errors).

Please remember that input of arguments into the program will be excepted only if you use:

int main(int argc, char* argv[])- as signature to the main function.

Actions in files

It is assumed that each line should have no more than 400 characters.

Decoding instructions in instruction file:

An instruction will appear in a line in the file (at the end of each instruction there will be a newline character). At the start of the running, the program will read the instruction line by line. Then it will decode the required action and parameters and will call to perform the action with the appropriate parameters.

Input of media components from file into list of media components

                                     Initialize

This is the first action in the action file. It is a signal that your program should decode the media component file hw_components.txt line by line, and then load the relevant media components into the linked list. Each media component will appear in a new line in the hw_components.txt file. (Components will be separated by ā€˜\n’.) The line will show the fields according to their order in the structure. "$$$" will serve as a separator between fields.

Example:

                                      Hub $$$ 120 
                                      Modem $$$ 80

Please pay attention to the fact that media components are not necessarily sorted by names.

Printing updated media components into updated media components file

                                      Finalize

This is the final action in instructions file. It is a signal that your program should go over the list of media components and print each component in updated_components.txt file according to given format – component name separated by "$$$" and number of the same component in inventory list. Products printed to updated_components.txt should be listed in lexicographically sorted manner. Once your program prints all the components, it should free all the allocated memory and exit. Pay attention: the main function should return 0 in case there were no errors during the program execution. In case of any error, the program should return a nonzero return code.

Actions.txt file Structure: Initialize ... Returned_from_customer $$$ Hub ultra $$$ 12 Fire $$$ Hub $$$ 13 (more on orders in the next page) ... Finalize

Pat attention: you may assume that the action file will always start with Initialize and end with Finalize commands. Also, the structure of instructions is always the same.

Supported Actions

1. Renaming the media component

      Rename $$$ current hw component name $$$ new hw component name

This action gets 2 parameters according to the following order – name of existing component and its new name. The action searches for component with an identical name to the one received. If the product with exactly the same name was found, it should be renamed accordingly. Otherwise, the action should be ignored. Pay attention: you should check the order of components list at the end of the action (the list needs to be sorted).

2. Returned media component ant Production of media component

        Returned_from_customer $$$ hw component name $$$ copies
        Production $$$ hw component name $$$ copies

On receiving those action command, your program should search in inventory for the component according to name and then update the number of components. If the component not in inventory, your program should update the list with a new component. The list should still be sorted according to component names.

Fire of components and Critical component failure

             Fatal_malfunction $$$ hw component name $$$ copies
             Fire $$$ hw component name $$$ copies

On receiving this action, your program should search for the component according to name. If the corresponding component is found, number of copies should be checked. If the number specified in the action description is greater than the number of available copies, only available copies should be destroyed, and the number of components should be updated to 0. If number of malfunctioning components is smaller than number of available copies, the action should update the number of available copies accordingly. If the component is not found, the action should be ignored.

This is my code :

#define _CRT_SECURE_NO_WARNINGS
#define NAME_LENGTH 200
#define MAX_action 11
#include <stdio.h>
#include <string.h>

typedef struct hw_component
{
    char name[NAME_LENGTH];
    int copies;
    struct hw_component *next;
}HW_component;

void free_list(HW_component* head)
{
    HW_component* temp;
    while (head != NULL)
    {
        temp = head;
        head = head->next;
        free(temp);
    }
}

HW_component* create_new_component(HW_component* head, char* name, int copies)
{
    HW_component *new_component = (HW_component*)malloc(sizeof(HW_component));
    if (new_component != NULL) {
        strcpy(new_component->name, name);
        new_component->copies = copies;
        new_component->next = NULL;
    }
    else {
        printf("Error: memory allocation failed\n");
        free_list(head);
        exit(1);
    }
    return new_component;
}

HW_component* add(HW_component* head, char* name, int copies) {
    HW_component* iter, *prev = NULL;
    HW_component* new_component = create_new_component(head, name, copies);
    if (head == NULL) {
        return new_component;
    }
    if (strcmp(new_component->name, head->name) < 0) {
        new_component->next = head;
        return new_component;
    }
    iter = head;
    while (iter != NULL && strcmp(new_component->name, iter->name) > 0) {
        prev = iter;
        iter = iter->next;
    }
    prev->next = new_component;
    new_component->next = iter;
    return head;
}

void read_line(FILE *fp, char *actions, char *component_name, char *component_name_2, int *num)
{
    int i = 0;
    char c = 0;
    *num = 0;
    c = getc(fp);
    while ((c != '\n') && (!feof(fp))) {
        for (i = 0; (c != '$') && (c != '\n') && (!feof(fp)); i++) {
            actions[i] = c;
            c = getc(fp);
        }
        actions[i] = '\0';
        if (c != '\n' && (!feof(fp))) {
            fseek(fp, 3, 1);
            c = getc(fp);
        }
        else break;
        for (i = 0; (c != '$') && (c != '\n'); i++) {
            component_name[i] = c;
            c = getc(fp);
        }
        component_name[i] = '\0';
        if (c != '\n' && (!feof(fp))) {
            fseek(fp, 3, 1);
            c = getc(fp);
        }
        else break;
        if (strcmp(actions, "Rename ") != 0) {
            for (i = 0; c != '\n'; i++) {
                *num = (*num) * 10 + (c - '0');
                c = getc(fp);
            }
        }
        else {
            for (i = 0; c != '\n'; i++) {
                component_name_2[i] = c;
                c = getc(fp);
            }
            component_name_2[i] = ' ';
            component_name_2[i + 1] = '\0';
        }
        return;
    }
}

HW_component* read_file_components(FILE *fp, HW_component *head, char *component_name, int *copies)
{
    int i = 0;
    char c = 0;
    *copies = 0;
    c = getc(fp);
    while ((c != '\n') && (!feof(fp))) {
        for (i = 0; (c != '$') && (c != '\n'); i++) {
            component_name[i] = c;
            c = getc(fp);
        }
        component_name[i] = '\0';
        if (c != '\n') {
            fseek(fp, 3, 1);
            c = getc(fp);
        }
        else break;
        for (i = 0; (c != '\n') && (!feof(fp)); i++) {
            *copies = (*copies) * 10 + (c - '0');
            c = getc(fp);
        }
        return add(head, component_name, *copies);
    }
    return head;
}

int actions_name(FILE* fp, char* actions)
{
    if (strcmp(actions, "Initialize") == 0)
        return 0;
    if (strcmp(actions, "Rename ") == 0)
        return 1;
    if ((strcmp(actions, "Returned_from_customer ") == 0) || (strcmp(actions, "Production ") == 0))
        return 2;
    if ((strcmp(actions, "Fatal_malfunction ") == 0) || (strcmp(actions, "Fire ") == 0))
        return 4;
    if (strcmp(actions, "Finalize") == 0)
        return 6;
}





HW_component* find(HW_component *head, char* component_name) {
    while (head != NULL && (strcmp(head->name,component_name)!=0))
        head = head->next;    
    return head;
}


HW_component* delete(HW_component *head, char *component_name, int copies)
{
    HW_component* iter = head, *prev = NULL;
    if (head == NULL)
        return head;
    if (strcmp(head->name, component_name) == 0)
    {
        iter = head->next;
        free(head);
        return iter;
    }
    prev = iter; iter = iter->next;
    while (iter != NULL)
    {
        if (strcmp(iter->name, component_name) == 0)
        {
            prev->next = iter->next;
            free(iter);
            break;
        }
        prev = iter;
        iter = iter->next;
    }
    return head;
}

HW_component* rename_function(HW_component *head, char *component_name, char* component_name_2)
{
    HW_component* new_head = head;
    int new_copies = 0;
    if (find(head, component_name) != NULL)
        strcpy(find(head, component_name)->name, component_name_2);
    new_copies = find(head, component_name_2)->copies;
    new_head = delete(head, component_name_2, new_copies);
    return add(new_head, component_name_2, new_copies);
}

HW_component* returned_from_customer_and_production_function(HW_component *head, char *component_name, int copies)
{
    HW_component* new_head = head;
    if (find(head, component_name) != NULL)
        find(head, component_name)->copies += copies;
    else {
        new_head = add(head, component_name, copies);
    }
    return new_head;
}



void fatal_malfunction_and_fire_function(HW_component *head, char *component_name, int copies) 
{
    if (find(head, component_name) != NULL)
        if (find(head, component_name)->copies <= copies)
            find(head, component_name)->copies = 0;
        else find(head, component_name)->copies -= copies;
    return;

}



void print_1_component(FILE *fp_update, HW_component *component_ptr)
{
    fprintf(fp_update, "%s$$$ %d", component_ptr->name, component_ptr->copies);
    return;
}

void print_components(FILE *fp_update, HW_component *head)
{
    HW_component* curr = head;
    while (curr != NULL) {
        print_1_component(fp_update, curr);
        curr = curr->next;
        if (curr != NULL) {
            fprintf(fp_update, "\n");
        }
    }
    return;
}

int main(int argc, char* argv[])
{
    FILE *fp_actions = NULL, *fp_hw_components = NULL, *fp_updated_components = NULL;
    HW_component *head = NULL;
    char actions[MAX_action], component_name[NAME_LENGTH + 1], component_name_2[NAME_LENGTH + 1];
    int copies = 0, *copies_ptr = &copies;

    if (argc != 4) 
    {
        printf("Error: invalid number of arguments (<%d> instead of 3)\n",argc);
        return 1;
    }

    if ((fp_hw_components = fopen(argv[1], "r")) == NULL) 
    {
        printf("Error: opening %s failed\n", fp_hw_components);
        return 1;
    }

    if ((fp_actions = fopen(argv[2], "r")) == NULL) 
    {
        printf("Error: opening %s failed\n", fp_actions);
        return 1;
    }

    while (!feof(fp_actions)) 
    {
        read_line(fp_actions, actions, component_name , component_name_2, copies_ptr);
        if (actions_name(fp_actions, actions) == 0) {
            while (!feof(fp_hw_components)) {
                head = read_file_components(fp_hw_components, head, component_name, copies_ptr);
            }
            fclose(fp_hw_components);
        }
        else if (actions_name(fp_actions, actions) == 1) {
            head = rename_function(head,component_name, component_name_2);
        }
        else if (actions_name(fp_actions, actions) == 2) {
            head =returned_from_customer_and_production_function(head, component_name, copies);
        }

        else if (actions_name(fp_actions, actions) == 4) {
            fatal_malfunction_and_fire_function(head, component_name, copies);
        }

        else if (actions_name(fp_actions, actions) == 6) {
            if ((fp_updated_components = fopen(argv[3], "w")) == NULL) {
                printf("Error: opening %s failed\n", fp_updated_components);
                return 1;
            }
            print_components(fp_updated_components, head);
            free_list(head);
            fclose(fp_updated_components);
        }
    }

    fclose(fp_actions);

    return 0;
} 

The input files:

actions.txt :

                Initialize
      Returned_from_customer $$$ Hub ultra $$$ 12
      Fire $$$ Hub $$$ 13
      Returned_from_customer $$$ Modem $$$ 12
      Production $$$ Nic $$$ 2
      Fire $$$ Router promore 10000GG $$$ 1
      Rename $$$ Router pro 100GG $$$ Router pro112 10000GG
      Returned_from_customer $$$ Hub pro $$$ 5
      Production $$$ Nic pro 2000GG $$$ 8
      Fatal_malfunction $$$ Nic 100GG $$$ 7
      Production $$$ Nic pro 2000GG $$$ 8000
      Returned_from_customer $$$ Hub ultraZZZZZ $$$ 12
               Finalize

hw_components.txt:

      Switch $$$ 80
      Nic $$$ 120
      Router $$$ 120
      Hub $$$ 120
      Modem $$$ 80
      Router promore 10000GG $$$ 80
      Router ultra $$$ 200
      Router pro 100GG $$$ 200
      Modem ultra $$$ 100
      Hub pro $$$ 150
      Switch pro $$$ 80
      Nic pro 2000GG $$$ 240
      Hub ultra $$$ 80
      Nic 100GG $$$ 20
      ZNic $$$ 20

the output file should be like : updated_components.txt:

      Hub $$$ 107
      Hub pro $$$ 155
      Hub ultra $$$ 92
      Hub ultraZZZZZ $$$ 12
      Modem $$$ 92
      Modem ultra $$$ 100
      Nic $$$ 122
      Nic 100GG $$$ 13
      Nic pro 2000GG $$$ 8248
      Router $$$ 120
      Router pro112 10000GG $$$ 200
      Router promore 10000GG $$$ 79
      Router ultra $$$ 200
      Switch $$$ 80
      Switch pro $$$ 80
      ZNic $$$ 20
c
file
pointers
linked-list
asked on Stack Overflow Jun 7, 2020 by user111 • edited Jun 7, 2020 by user111

1 Answer

0

At the very least, you are not passing the correct parameters to your own functions. The function rename_function accepts a HW_component* and two strings, but you're passing it a HW_component*, one string, and an int.

Also, action_name should do something if the input doesn't match any of the action strings. Right now it just returns a random int.

There are also some places where you're passing FILE* to printf instead of a string (a char*).

I recommend you compile your code with maximum warnings and fix all the warnings. This is a pretty ordinary C program and should compile with no warnings at all.

answered on Stack Overflow Jun 7, 2020 by Willis Blackburn

User contributions licensed under CC BY-SA 3.0