C读取字符串并动态接受括号

我要读一串括号来分析它。 如何读取要插入动态生成的数组中的字符串?

除了使用scanf的括号外,如何避免读取所有字符? [] {}()

谢谢。

编辑:我必须从键盘读取一系列括号,但我不知道长度。 所以我要创建一个动态生成的数组(这是一个要求),只包含括号的空格。 当我正在阅读时,我想只接受括号并避免使用所有其他字符,这是否可以与正则表达式的scanf一起使用?

只需使用if条件检查所有括号。 假设ch是包含输入字符串的数组,那么:

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

除了使用scanf的括号外,如何避免读取所有字符? [] {}()

代码不能。 在某种程度上,代码正在读取用户类型的任何内容,包括[ ] { } ( )和不包含的字符。 最好的是代码读取输入然后选择性对它进行操作,即使这意味着读取和抛掷数据。 在任何情况下,OP当然也希望读取'\n'来知道何时停止。

使用fgets()最适合用户输入@Michael Walz ,但OP报告必须使用scanf()

scanf()有一个扫描集说明符,允许只读取选择的字符,而其他字符保留在stdin扫描集"%[...]" ,其中...为所需字符。 如果希望成为扫描集的一部分,它应该是第一个。

由于未指定输入长度的上限,因此代码可以危险地存在并且根据需要简单地重新分配存储器以通过一次读取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); } } 

所以,我假设你的简介是从输入文本中删除括号字符并存储它们以供以后分析。 假设这是正确的,这里有一个你可能会觉得有用的通行证:

 #include  #include  #include  #include  /** * 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: ((()))[[[[]]]]{}()[]{}[]