Как перенаправить ввод в мою C программу из аргументов файла и командной строки на узел графа? - PullRequest
0 голосов
/ 16 апреля 2020

узел графа выглядит следующим образом

typedef struct node{
int x_position, y_position;
int max_rate, min_rate;
char *name;
struct node * prev;
}Node;

вводит текстовый файл следующим образом

2 2 200 300 name
1 5 240 499 name2
3 5 400 500 name3
...

эта программа запускается с аргументами командной строки следующим образом

./program arg1 arg2 arg3 arg4 arg5 < input.txt

Я хочу чтобы хранить их все в отдельных переменных, аргументы командной строки assingned_val1 = arg1 ,assigned_val2 = arg2 ...,

и содержимое input.txt назначают переменные графа my Node следующим образом

1 1 100 300 Gerald --> node( x_position = 1; y_position =1
                           min_rate = 100 ; max_rate = 300
                           name = "Gerald" 
2 3 200 450  Yennefer --> node( x_position = 2; y_position =3
                           min_rate = 200 ; max_rate = 450
                           name = "Yennefer"

... How это можно решить с помощью C программирования?

Ответы [ 2 ]

1 голос
/ 16 апреля 2020

вы можете использовать atoi для преобразования строки в int и strcpy для копирования строки в строку:

    int arg1, arg2, arg3, arg4;
    char arg5[256];

    arg1 = atoi(argv[1]);
    arg2 = atoi(argv[2]);
    arg3 = atoi(argv[3]);
    arg4 = atoi(argv[4]);
    strcpy(arg5, argv[5]);

Для получения информации из файла вы можете использовать fgets и sscanf , Этот пример ниже только для массива count узла (не для связанного списка, но вы можете использовать эту идею для связанного списка). fgets для чтения файла и сохранения значения файла в строке. Вы можете использовать sscanf для присвоения информации из этой строки каждому значению структуры.

    int count = 1;
    while (fgets(line, sizeof(line), file)) {
        n = realloc(n, count * sizeof(Node));
        n[count-1].name = malloc(sizeof(char) * 16);
        if(!n)
            return - 1;
        sscanf(line, "%d %d %d %d %s\n", &n[count-1].x_position, &n[count-1].y_position, &n[count-1].min_rate, &n[count-1].max_rate, n[count-1].name);
        count++;
    }

Полный код для теста:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct node{
    int x_position, y_position;
    int max_rate, min_rate;
    char *name;
    //struct node * prev;
}Node;

int main(int argc, char const *argv[]) {
    char line[256];
    int arg1, arg2, arg3, arg4;
    char arg5[256];
    Node * n = malloc(sizeof(Node));
    if(!n)
        return - 1;
    FILE * file = fopen(argv[6], "r");
    if (!file)
        return -1;
    arg1 = atoi(argv[1]);
    arg2 = atoi(argv[2]);
    arg3 = atoi(argv[3]);
    arg4 = atoi(argv[4]);
    strcpy(arg5, argv[5]);

    int count = 1;
    while (fgets(line, sizeof(line), file)) {
        n = realloc(n, count * sizeof(Node));
        n[count-1].name = malloc(sizeof(char) * 16);
        if(!n)
            return - 1;
        //printf("%s", line); 
        sscanf(line, "%d %d %d %d %s\n", &n[count-1].x_position, &n[count-1].y_position, &n[count-1].min_rate, &n[count-1].max_rate, n[count-1].name);
        count++;
    }

    printf("\narg1= %d, arg2 = %d, arg3 = %d, arg4 = %d, arg5 = %s\n", arg1, arg2, arg3, arg4, arg5);

    for(int i = 0; i < count-1; i++) {
        printf(" %d  %d  %d  %d  %s\n",
        n[i].x_position, n[i].y_position, n[i].min_rate, n[i].max_rate, n[i].name);
    }

}

Результат:

#cat text.txt

2 2 200 300 name
1 5 240 499 name2
3 5 400 500 name3
./test 1 2 3 4 abc text.txt

arg1= 1, arg2 = 2, arg3 = 3, arg4 = 4, arg5 = abc
 2  2  200  300  name
 1  5  240  499  name2
 3  5  400  500  name3
0 голосов
/ 16 апреля 2020

Вы также можете использовать входной файл, такой как этот, содержащий данные, которые вы показываете, например.

1 1 100 300 Gerald
2 3 200 450 Yennefer
...

Затем передайте только один аргумент командной строки, путь и имя файла, например:
executable.exe "C:\\filename.txt"
Это позволит программе легче разместить столько игроков, сколько необходимо в одном шаг и исключить пользовательский ввод, который подвержен синтаксическим несоответствиям, делая анализ данных трудным или невозможным.

Этот файл можно прочитать и проанализировать, как показано ниже, используя следующие функции:
fopen fclose )
fgets
strtok ,
strtol .

Код для выполнения чтения и анализа (с минимальной проверкой ошибок):

typedef struct node{
    int x_position;
    int y_position;
    int max_rate;
    int min_rate;
    char *name;
    struct node * prev;
}Node;

int linecount(const char *file);

int main(int argc, char *argv[])
{
    char line[80];
    char *tok = NULL;
    char *temp;
    errno = 0;
    int count = 0;

    if(argv != 2) 
    { 
        //exit with message
    }

    count = linecount(argv[1]);
    Node *n = calloc(count, sizeof(*n));

    FILE *fp = fopen(argv[1], "r");
    if(fp)
    {
        while(fgets(line, 80, fp))
        {
            tok = strtok(line, " ");//parse x_position
            if(tok)
            {
                n->x_position = strtol(tok, &temp, 0);
                tok = strtok(NULL, " ");//parse y_position
                if(tok)
                {
                    n->y_position = strtol(tok, &temp, 0);
                    tok = strtok(NULL, " ");//parse max_rate
                    if(tok)
                    {
                        n->max_rate = strtol(tok, &temp, 0); 
                        tok = strtok(NULL, " ");//parse min_rate
                        if(tok)
                        {
                            n->min_rate = strtol(tok, &temp, 0);
                            tok = strtok(NULL, " ");//parse name
                            if(tok)
                            {
                                strcpy(n->name, tok);
                            }
                        }

                    }

                }
            }
        }
        fclose(fp);
    }
    return 0;

}

int linecount(const char *file)
{
    char line[80];
    int i = 0;

    FILE *fp = fopen(file, "r");
    if(fp)
    {
        while(fgets(line, 80, fp))
        {
            i++;
        }
        fclose(fp);
    }
    return i;
}
...