我正在开展一个项目,我在这个项目中给出了一个以这种格式的标题开头的文件:a1,b3,t11, 2,,5,\3,*4,344,00,
。它始终是一个ASCII字符的序列,后跟一个用逗号分隔的整数,其序列始终以00,
结尾。
基本上我要做的就是通过这个并将每个字符/整数对放入我拥有的数据类型中,将这两个作为参数并生成这些参数。例如,我上面给出的标题是一个以('a',1), ('b',3),('t',11),(',',5)(' ',2),('\',3),('*',4),('3',44)
为元素的向量。
我在解析它时遇到了麻烦。到目前为止我还是:
我知道我可以很容易地根据逗号分割我的字符串,但我不知道如何做到这一点,仍然将字符中的整数分开,同时保留两者并计算我需要视为字符的整数。
非常感谢任何建议或有用的标准库或字符串函数。
答案 0 :(得分:0)
由于您已经发现可以忽略最后3个字符,因此使用sscanf就足够了。 您可以使用sscanf读取一个字符(或getch函数),使用sscanf读取整数,最后甚至忽略一个字符。
如果您在理解如何操作时遇到问题,请注释。
答案 1 :(得分:0)
许多人的一种可能性是将数据存储在结构中。这使用了一组结构,但可以根据需要使用malloc
和realloc
分配结构
解析字符串可以使用指针和strtol
完成,它将解析整数并给出指向整数后面的字符的指针。可以将该指针前进以在下一次迭代中使用以获取ASCII字符和整数。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 100
struct pair {
char ascii;
int integer;
};
int main( void) {
char input[] = "a1,b3,!0,t11, 2,,5,\\3,*4,34400,";
char *pt = input;//start with pt pointing to first character of input
char *end = input;
int each = 0;
int loop = 0;
int length = 0;
struct pair pairs[SIZE] = { { '\0', 0}};
//assuming input will always end in 00, ( or ,00,)
//remove those three ( or 4 ??) characters
length = strlen ( input);
if ( length > 3) {
input[length - 3] = '\0';
}
for ( each = 0; each < SIZE; each++) {
//get the ASCII character and advance one character
pairs[each].ascii = *pt;
pt++;
//get the integer
pairs[each].integer = strtol ( pt, &end, 10);
//end==pt indicates the expected integer is missing
if ( end == pt) {
printf ( "expected an integer\n");
break;
}
//at the end of the string?
if ( *end == '\0') {
//if there are elements remaining, add one to each as one more was used
if ( each < SIZE - 1) {
each++;
}
break;
}
//the character following the integer should be a comma
if ( *end != ',') {
//if there are elements remaining, add one to each as one more was used
if ( each < SIZE - 1) {
each++;
}
printf ( "format problem\n");
break;
}
//for the next iteration, advance pt by one character past end
pt = end + 1;
}
//loop through and print the used structures
for ( loop = 0; loop < each; loop++) {
printf ( "ascii[%d] = %c ", loop, pairs[loop].ascii);
printf ( "integer[%d] = %d\n", loop, pairs[loop].integer);
}
return 0;
}
另一种选择是使用动态分配
这也使用sscanf来解析输入。 %n
将捕获扫描处理的字符数。然后可以使用offset
和add
变量来迭代输入。最后一次扫描只捕获ascii字符和整数,sscanf的返回值为2。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct pair {
char ascii;
int integer;
};
int main( void) {
char input[] = "a1,b3,!0,t11, 2,,5,\\3,*4,34400,";
char comma = '\0';
char ascii = '\0';
int integer = 0;
int result = 0;
int loop = 0;
int length = 0;
int used = 0;
int add = 0;
int offset = 0;
struct pair *pairs = NULL;//so realloc will work on first call
struct pair *temp = NULL;
//assuming input will always end in 00, ( or ,00,)
//remove those three ( or 4 ??) characters
length = strlen ( input);
if ( length > 3) {
input[length - 3] = '\0';
}
while ( ( result = sscanf ( &input[offset], "%c%d%c%n"
, &ascii, &integer, &comma, &add)) >= 2) {//the last scan will only get two items
if ( ( temp = realloc ( pairs, ( used + 1) * sizeof ( *pairs))) == NULL) {
fprintf ( stderr, "problem allocating\n");
break;
}
pairs = temp;
pairs[used].ascii = ascii;
pairs[used].integer = integer;
//one more element was used
used++;
//the character following the integer should be a comma
if ( result == 3 && comma != ',') {
printf ( "format problem\n");
break;
}
//for the next iteration, add to offset
offset += add;
}
for ( loop = 0; loop < used; loop++) {
printf ( "ascii[%d] = %c ", loop, pairs[loop].ascii);
printf ( "value[%d] = %d\n", loop, pairs[loop].integer);
}
free ( pairs);
return 0;
}