2016-12-16 12 views
0

Я должен прочитать строку скобок, чтобы проанализировать это. Как я могу прочитать строку, которая будет вставлена ​​в массив, генерируемый динамически?C чтение строки и принимает только скобки динамически

Как я могу избежать всех символов чтения, кроме скобок, используя scanf? [] {}()

спасибо.

Редактировать: Мне нужно прочитать ряд кронштейнов с клавиатуры, но я не знаю длины. Поэтому я должен создать динамически генерируемый массив (это требование), чтобы содержать только пространство скобок. Пока я читаю, я хочу принимать только скобки и избегать всех других символов, возможно ли это с помощью scanf с регулярным выражением?

+1

Не используйте '' scanf' но fgets'. –

+0

Почему? fgets помогают мне генерировать динамически массив? –

+0

Я не использую файлы. –

ответ

1

Просто проверьте все скобы, используя if состояние. Предположим, если ch является массив, содержащий входную строку, то:

if(ch[0]=='[' || ch[0]==']'||...){ 
// process the bracket and do same for all other ch indeces. 
} 
+0

Я хочу избежать этого метода и использовать регулярное выражение с scanf ... возможно ли это? –

+0

@ user3122577 Вы не указали _regex_ в своем вопросе. –

+0

U правые, я изменил вопрос. Сожалею. –

0

Как я могу избежать всех символов от чтения для консолей с зсапЕ исключением? [] {}()

Код не может. На некотором уровне код считывает все типы пользователей, включая [ ] { } (), и символы, которых нет. Лучше всего использовать код для чтения ввода, а затем избирательность работает на нем, даже если это означает чтение и подбрасывание данных. В любом случае, OP обязательно хочет прочитать '\n', чтобы знать, когда остановиться.

Использование fgets() является лучшим для пользовательского ввода @Michael Walz, но OP reports необходимо использовать scanf().

scanf() имеет сканирования набор спецификатор, который позволяет только для чтения выберите символы, оставляя другие, чтобы остаться в stdin. A набор для сканирования - "%[...]" с ... в качестве желаемых символов. Если ] является частью набора сканирования, он должен быть первым.

Поскольку не указано верхняя граница входной длины, код может жить опасно и просто перераспределять память по мере необходимости для ввода пользовательского ввода путем считывания 1 символа за раз.

Ниже некоторые из них не так эффективного кода, который соответствует целям:

char *bracket_read(void) { 
    size_t brackets_length = 0; 
    // Allocate +2, 1 for the null character and 1 for the potential next character 
    char *brackets = malloc(brackets_length + 2); 
    assert(brackets); 
    brackets[brackets_length] = '\0'; 

    char non_bracket = 0; 
    while (non_bracket != '\n') { 
    #define SCAN_SET "][(){}" 
    int cnt = scanf("%1[" SCAN_SET "]", &brackets[brackets_length]); 
    if (cnt == 1) { 
     brackets_length++; 
     char *t = realloc(brackets, brackets_length + 2); 
     assert(t); 
     brackets = t; 
    } else { 
     // Quietly consume other characters 
     if (scanf("%c", &non_bracket) == EOF) { 
     if (brackets_length == 0) { 
      free(brackets); 
      return NULL; 
     } 
     non_bracket = '\n'; 
     } 
    } 
    } 
    return brackets; 
} 

int main() { 
    char *s; 
    while ((s = bracket_read()) != NULL) { 
    printf(".%s.\n", s); 
    fflush(stdout); 
    free(s); 
    } 
} 
0

Итак, я предполагаю, что ваш Бриф раздеться кронштейном символов из входного текста и сохранять их для последующего анализа. Если предположить, что это правильно, вот один проход, который Вы можете найти полезным:

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

/** 
* Input buffer size 
*/ 
#define BUFSIZE 20 

/** 
* Extends the target buffer by doubling its size. 
* If the realloc call fails, the original buffer 
* is left intact. 
*/ 
int extend(char **buffer, size_t *bufferSize) 
{ 
    char *tmp = realloc(*buffer, *bufferSize * 2); 
    if (tmp) 
    { 
    *buffer = tmp; 
    *bufferSize *= 2; 
    } 

    return tmp != NULL; 
} 

int main(void) 
{ 
    /** 
    * Fixed buffer for reading from input stream 
    */ 
    char inputBuffer[BUFSIZE+1] = {0}; 
    /** 
    * Dynamically allocated target buffer that can be extended as necessary 
    */ 
    char *targetBuffer = NULL; 
    size_t targetBufferSize = sizeof *targetBuffer * sizeof inputBuffer; 
    size_t targetBufferPos = 0; 
    int done = 0; 
    char fmt[20] = {0}; 

    /** 
    * Allocate the target buffer, which is initially the same size as the input buffer. 
    */ 
    if (!(targetBuffer = malloc(targetBufferSize))) 
    { 
    fprintf(stderr, "FATAL: could not allocate memory for targetBuffer\n"); 
    exit(EXIT_FAILURE); 
    } 

    /** 
    * Create our input format string. Since we're using the [ conversion 
    * specficier, we need to also specify the max size we want to read at 
    * one time using the field width specifier. Unfortunately, you can't 
    * pass the field width as an argument in scanf the way you can with 
    * printf, so we have to create the format string and save it to its 
    * own buffer. When we're done, it will be "%20[^\n]%c". 
    */ 
    sprintf(fmt, "%%%zu[^\n]%%c", sizeof inputBuffer - 1); 

    while (!done) 
    { 
    char follow; 

    /** 
    * Read BUFIZE characters plus a "follow" character. If the "follow" character 
    * is a newline, then we've read the complete input line and don't need 
    * to loop again. Otherwise, push the "follow" character back onto the input 
    * stream for the next read. 
    */ 
    if (scanf(fmt, inputBuffer, &follow) < 1) 
    { 
     fprintf(stderr, "FATAL: error on read\n"); 
     free(targetBuffer); 
     exit(EXIT_FAILURE); 
    } 

    if (follow == '\n') 
     done = 1; 
    else 
     ungetc((int) follow, stdin); 

    /** 
     * Walk down our input buffer; if the next character is one of '[', ']', '{' , '}', 
     * '(', or ')', append it to the target buffer. 
     */ 
    char *p = inputBuffer; 
    while (*p) 
    { 
     if (*p == '[' || *p == ']' || *p == '{' || *p == '}' || *p == '(' || *p == ')') 
     { 
     /** 
      * Before we append a character to the target buffer, we first need to make 
      * sure there's room left (targetBufPos < targetBufSize). If there isn't 
      * any room left, we need to extend the target buffer before appending to it. 
      * 
      * We're taking advantage of the short-circuit nature of the || operator. Remember 
      * that given the expression a || b, if a evaluates to true, then the whole 
      * expression evaluates to true regardless of the value of b, so b isn't 
      * evaluated at all. 
      * 
      * If targetBufferPos < targetBufferSize evaluates to true (non-zero), then 
      * the extend function isn't called; we simply append to the target buffer. 
      * 
      * If targetBufferPos < targetBufferSize is *not* true, then the extend 
      * function is called. If extend returns true (non-zero), then the operation 
      * succeeded and we append to the now-lengthened target buffer. If extend 
      * returns false (zero), then the operation failed and we bail out with an error. 
      */ 
     if (targetBufferPos < targetBufferSize || extend(&targetBuffer, &targetBufferSize)) 
     { 
      targetBuffer[targetBufferPos++] = *p; 
     } 
     else 
     { 
      fprintf(stderr, "FATAL: could not extend memory for targetBuffer\n"); 
      free(targetBuffer); 
      exit(EXIT_FAILURE); 
     } 
     } 
     p++; 
    } 
    } 
    /** 
    * We're treating targetBuffer as a string, so we need to add 
    * the 0 terminator to the end. Again, we first need to make 
    * sure there's room in the buffer, and if not, to extend it. 
    * 
    * Yes, there's a corner case here where you're doubling the buffer 
    * size to add one more character. I'm not going to worry about it 
    * here, but it's easy enough to fix. 
    */ 
    if (targetBufferPos < targetBufferSize || extend(&targetBuffer, &targetBufferSize)) 
    { 
    targetBuffer[targetBufferPos++] = 0; 
    } 
    else 
    { 
    fprintf(stderr, "FATAL: could not extend memory for targetBuffer\n"); 
    free(targetBuffer); 
    exit(EXIT_FAILURE); 
    } 

    printf("Found the following bracket characters in the input string: %s\n", targetBuffer); 
    free(targetBuffer); 
    return EXIT_SUCCESS; 
} 

Пример запуска:

$ ./scanner 
(((This))) [[[[is]]]] {a} (T)[e]{s}[t] 
Found the following bracket characters in the input string: ((()))[[[[]]]]{}()[]{}[]