Сканирование группы целых чисел в виде (x, y) в c - PullRequest
2 голосов
/ 02 апреля 2019

Input from user Я пытаюсь получить входные данные от стандартного ввода в форме (a, b) (c, d) (e, f) (g, h) и перестану принимать вводесли добавлена ​​пустая строкаМне нужно, чтобы эти входы кортеж кортежем, как (a, b) сначала, затем я выполняю некоторые вычисления с ним, как добавить в двоичном дереве и добавить (c, d) затем (e, f) и так далее следующим образом:

insert_in_tree(&tree->root,&tree->root,a, b);

Я знаю, как принимать целые числа до тех пор, пока не будет добавлена ​​пустая строка, что я делаю следующим образом:

AVLTree *CreateAVLTree(const char *filename)
{
    // put your code here
    AVLTree *tree = newAVLTree();
    int key, value;
    if(strcmp(filename, "stdin") == 0){
        char str[1024]={};
        printf("Enter your values");
        while( fgets(str, 1024, stdin) && strlen(str) && str[0] != '\n' ){
            printf("string %s", str);
            sscanf(str, "%d, %d", &key, &value);
            //int key = atoi(str);
            printf("This is key you entered %d\n", key);
            printf("This is value you entered %d\n", value);
        }
    }else{
    FILE* file = fopen(filename, "r"); // open a file
    if(file == NULL) {
        return NULL;                                   // error checking
    }
    while (fscanf (file, " (%d,%d)", &key, &value) == 2)  // check for number of conversions
    //  space added  here ^
    {

        insert_in_tree_q5(&tree->root,&tree->root, key, value);
        //printf("%d,%d\n", key, value);
    }
    fclose(file);
    //node = tree->root;
}
    return tree;
}

, но я не уверен, как использовать это для решения моей проблемы, изложенной выше.

1 Ответ

0 голосов
/ 02 апреля 2019

Я не фанат использования scanf() et.al.для анализа данных, так как простой scanf("%d,%d") склонен к ошибкам при различном вводе пользователем.

Мой общий подход при работе с известными символами форматирования (такими как (, ,, )),это сначала найти их с помощью strchr(), подтвердить, что они несколько разумны, и только затем попытаться извлечь значение.

В приведенном ниже коде я нахожу скобки и запятую, затем копирую возможно числовые данные между ними, прежде чем передать их strtol() для преобразования целочисленной строки в числовое представление.

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

#define MAX_NUMBER_LEN 32

/*
** Given a string which contains (somewhere) a pair
** of numbers in the form "... (x, y) ...", parse the pair
** into val1 and val2 respectively.
**
** Returns the point at which the input ended successfully
** or NULL on error
*/
const char *parseTuple(const char *input, int *val1, int *val2)
{
    char *result = NULL;
    char  val1_str[ MAX_NUMBER_LEN+1 ] = { '\0' }; 
    char  val2_str[ MAX_NUMBER_LEN+1 ] = { '\0' };

    // Find the first '('
    char *left_paren  = strchr( input, '(' );
    char *right_paren = strchr( input, ')' );
    char *comma       = strchr( input, ',' );

    // validate the things we found exist, and are in valid positions
    if ( left_paren != NULL && right_paren != NULL && comma != NULL &&   // needed parts exist
         left_paren < comma && comma < right_paren )                     // in the correct order

    {
        // val1 source string exists between left_paren+1 and comma-1
        int val1_len = comma-1 - left_paren+1 - 1;
        if ( val1_len > 0 && val1_len < MAX_NUMBER_LEN )
        { 
            strncpy( val1_str, left_paren+1, val1_len );
            val1_str[ val1_len ] = '\0';
        }

        // val2 source string exists between comma+1 and right_paren-1
        int val2_len = right_paren-1 - comma+1 - 1;
        if ( val2_len > 0 && val2_len < MAX_NUMBER_LEN )
        { 
            strncpy( val2_str, comma+1, val2_len );
            val2_str[ val2_len ] = '\0';
        }

        // If we extracted some reasonable numbers, try to parse them
        if ( val1_str[0] != '\0' && val2_str[0] != '\0' )
        {
            *val1 = strtol( val1_str, NULL, 10 );
            *val2 = strtol( val2_str, NULL, 10 );
            // TODO handle errno when string is not a number

            // if errono did not indicate a strol() failure
            result = right_paren+1;  // point to the next input location, so we can call again 
        }
    }

    return result;
}



int main(int argc, char **argv)
{
    const char *input;
    int val1;
    int val2;

    for (int i=1; i<argc; i++)
    {
        input = argv[i];

        do
        {
            printf( "From input of: [%s]\n" , input );
            input = parseTuple( input, &val1, &val2 );
            if ( input != NULL )
                printf( "    Parsed out: (%3d,%3d)\n", val1, val2 );

        } while ( input != NULL && strlen( input ) );
    }

    return 0;
}

Предоставление тестового прогона:

$ ./parse_tuple '(-3, 2)' '(1,1)(11111111111111111111111111111111111111111111111111111111111111111111,0) () (,)' '(' '()' ')' '(,)' '(-12,)' '(123,456)'
From input of: [(-3, 2)]
    Parsed out: ( -3,  2)
From input of: [(1,1)(11111111111111111111111111111111111111111111111111111111111111111111,0) () (,)]
    Parsed out: (  1,  1)
From input of: [(11111111111111111111111111111111111111111111111111111111111111111111,0) () (,)]
From input of: [(]
From input of: [()]
From input of: [)]
From input of: [(,)]
From input of: [(-12,)]
From input of: [(123,456)]
    Parsed out: (123,456)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...