Как сканировать, пока я не получу что-то не такой же формы - PullRequest
0 голосов
/ 13 октября 2019

Я ввожу текстовый файл из Stdin, который будет иметь неопределенное количество координат, затем #, затем другой набор координат. Как мне отсканировать координаты в цикл, который останавливается, когда я нажимаю на #, что позволяет мне сканировать остальные координаты после #?

Я пробовал пару циклов, таких как:

    `while(scanf("[%d,%d]\n", &x, &y) == 1){

        //do stuff//

}

но я не чувствую, что я все ближе к ответу, любая помощь будет принята с благодарностью, ура

пример ввода (# не имеет "" вокруг него, но исчезает здесь, если оноdoenst):

[0,0]  
[1,1]  
[2,2]  
"#"  
[1,3]  
[3,6]  
[9,8]

Ответы [ 2 ]

0 голосов
/ 13 октября 2019

Ваши входные данные, разделенные двойными кавычками "#", немного усложняют ситуацию. Ваша попытка чтения с scanf обречена на провал. Ваша строка формата scanf, равная "[%d,%d]\n", не считывает / не удаляет '\n' в конце строки. На самом деле это не соответствует '\n' вообще. scanf не интерпретирует управляющие символы, поэтому то, что ищет '\n' в вашей строке формата, это литерал 'n', приводящий к input-fail после двух преобразований.

У вас есть два варианта:

  1. удалить '\n' из строки формата, продолжить с scanf (не рекомендуется), а затем вручную прочитать / отбросить все оставшиеся символы в строке до'\n' достигнут (используя getchar() или fgetc());или
  2. считывание каждой строки в буфер с использованием строчно-ориентированной функции ввода, такой как fgets() или POSIX getline(), чтобы каждый раз считывать полную строку данных, а затем анализироватьнеобходимая информация из буфера с помощью sscanf (предпочтительный метод).

Используя приведенный выше предпочтительный подход, вы можете сделать что-то похожее на:

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

#define MAXC 1024   /* if you need a constant, #define one (or more) */

int main (void) {

    char buf[MAXC];     /* buffer for each line */
    int x, y, n = 0;    /* coordinates & counter */

    printf ("set[%d]:", n++);                   /* initial set[]: label */
    while (fgets (buf, MAXC, stdin)) {          /* read each line */
        if (strncmp (buf, "\"#\"", 3) == 0)     /* line starts with "#"? */
            printf ("\nset[%d]:", n++);         /* output new set[]: label */
        else if (sscanf (buf, " [%d,%d]", &x, &y) == 2) /* 2 conversions? */
            printf (" %d,%d", x, y);            /* output coordinates */
    }
    putchar ('\n');     /* tidy up with newline */

    return 0;
}

(примечание: , если ваш файл просто содержит # вместо "#", вы можете просто проверить первый символ в буфере вместо использования strncmp)

Пример входного файла

$ cat dat/coordgroups.txt
[0,0]
[1,1]
[2,2]
"#"
[1,3]
[3,6]
[9,8]

Пример использования / Вывод

$ ./bin/readcoords < dat/coordgroups.txt
set[0]: 0,0 1,1 2,2
set[1]: 1,3 3,6 9,8

Посмотрите и дайте мне знать, если у вас есть дополнительные вопросы.

0 голосов
/ 13 октября 2019

Вы, вероятно, хотите заключить код в fgets (или readline):.

    char buff[2048] ;
    while ( fgets(buff, sizeof(buff), stdin )) {
        // Check of 'last' marker
        if ( buff[0] == '#' ) break ;
        // Check if looks like coordinates
        if ( sscanf(buff, "[%d,%d]\n", &x, &y) == 2 ) {
             // do something
        } ;
    } ;
  • Незначительное исправление кода возврата sscanf (2 вместо 1) - проверка на синтаксический анализ 2 полей
...