如何处理从复杂输入中提取双重类型数字(字符串)

祝大家好日子,

我对C编程很陌生,我偶然发现了一个问题,试图在几天内正确地解决,但仍然没有令人满意的结果。

我试图从这个forms的输入中提取一些double{[ 5.1 ; 4 ], [15.3 ; -3.2] } {[ 5.1 ; 4 ], [15.3 ; -3.2] } {[ 5.1 ; 4 ], [15.3 ; -3.2] } 。 我尝试了很多方法,到目前为止最好的方法是我使用fgets()读取用户输入作为字符串,使用for循环,如果isdigit()看到一个数字我将它存储在另一个字符串中,然后我检查是否有在数字后面点,如果有,那么我把它放在数字后面的字符串,依此类推。

真正的问题是,当我想输出结果字符串并使用strtod()将其转换为我想要的double ,它只有在用户首先输入一些数字时才有效,但是如果输入看起来像{ [ 2.5 ; 1 ] } { [ 2.5 ; 1 ] }代码只是不关心,什么都不做。 任何帮助或见解将不胜感激,也许我采取了错误的方法? 谢谢。

我的代码

 #include  #include  #include  #include  #include  #define STR_LEN 256 int main() { char t1[STR_LEN], digits[STR_LEN], *dpt, per[2] = "."; int i, digit, period; double x; fgets(t1, STR_LEN, stdin); for (i = 0; i < strlen(t1); i++) { digit = isdigit(t1[i]); period = (t1[i + 1] == '.') ? 1 : 0; if (digit) { digits[i] = t1[i]; } if (period == 1) { strcpy(digits, digits); strcat(digits, per); } } x = strtod(digits, &dpt); int testOutput = strlen(digits); printf("%s %d %lf", digits, testOutput, x); return 0; } 

索引到digits时需要一个单独的索引变量(与i不同)。 这是因为如果您的输入是(例如; 37.5 ), i将在digits上未对齐

此外,当您将数字复制到digits ,您必须添加一个EOS终止符以保持字符串整数[以便strcat不会在digits字符串的末尾运行]。

你不想在循环中使用t1[i + 1] 。 它可能超出输入的结尾,所以使用t1[i] (即在下一个循环迭代中找到句点)


这是你的代码的工作版本[请原谅无偿的样式清理]:

 #include  #include  #include  #include  #include  #define STR_LEN 256 int main() { char t1[STR_LEN], digits[STR_LEN], *dpt, per[2] = "."; int i, idig, digit, period; double x; fgets(t1, STR_LEN, stdin); idig = 0; for (i = 0; i < strlen(t1); i++) { digit = isdigit(t1[i]); period = (t1[i] == '.') ? 1 : 0; if (digit) { digits[idig++] = t1[i]; digits[idig] = 0; } if (period == 1) { //strcpy(digits, digits); strcat(digits, per); idig += 1; } } x = strtod(digits, &dpt); int testOutput = strlen(digits); printf("%s %d %lf\n", digits, testOutput, x); return 0; } 

我简化了一下代码:

 #include  #include  #include  #include  #include  #define STR_LEN 256 int main() { char t1[STR_LEN]; char digits[STR_LEN]; char *dpt; int isrc, idig; int len; int chr; double x; fgets(t1, STR_LEN, stdin); len = strlen(t1); idig = 0; for (isrc = 0; isrc < len; ++isrc) { chr = t1[isrc]; if (isdigit(chr)) { digits[idig++] = chr; continue; } if (chr == '.') { digits[idig++] = chr; continue; } } digits[idig] = 0; x = strtod(digits, &dpt); int testOutput = strlen(digits); printf("%s %d %lf\n", digits, testOutput, x); return 0; } 

这是使用char *指针而不是索引变量的第三个版本:

 #include  #include  #include  #include  #include  #define STR_LEN 256 int main() { char t1[STR_LEN]; char digits[STR_LEN]; char *dpt; char *src; char *dst; int isrc, idig; int len; int chr; double x; fgets(t1, sizeof(t1), stdin); src = t1; dst = digits; for (chr = *src++; chr != 0; chr = *src++) { if (isdigit(chr)) { *dst++ = chr; continue; } if (chr == '.') { *dst++ = chr; continue; } } *dst = 0; x = strtod(digits, &dpt); int testOutput = strlen(digits); printf("%s %d %lf\n", digits, testOutput, x); return 0; } 

试试这个:

 #include  #include  #include  struct Pair { double first; double second; struct Pair * tail; }; void printPairs( const struct Pair * node ) { if( node->tail ) { printPairs( node->tail ); } printf( "[ %3.2f ; %3.2f ]\n", node->first, node->second ); } int main() { const char * input = "some words before {[ 5.1 ; 4 ], [15.3 ; -3.2] } some words after"; struct Pair * head = NULL, * p = NULL; char * err = NULL; double first, second; const char * s = strchr( input, '{' ); while( s ) { s = strchr( s, '[' ); if( ! s ) { break; } while( *s == ' ' || *s == '[' ) { ++s; } first = strtod( s, &err ); if( err && ( *err == ' ' || *err == ';' )) { s = err + 1; while( *s == ' ' || *s == ';' ) { ++s; } second = strtod( s, &err ); if( err && ( *err == ' ' || *err == ']' )) { p = (struct Pair *)calloc( 1, sizeof( struct Pair )); p->first = first; p->second = second; p->tail = head; head = p; } else { fprintf( stderr, "Parse error, space or ']' expected\n" ); exit( EXIT_FAILURE ); } } else { fprintf( stderr, "Parse error, space or ';' expected\n" ); exit( EXIT_FAILURE ); } } printPairs( head ); } 

输出:

 [ 5.10 ; 4.00 ] [ 15.30 ; -3.20 ]