你得到奇怪字符的原因是scanf()不返回扫描值,它返回匹配格式的项目数。
您正在以一种调用未定义行为的方式调用scanf()。当您使用 "%d" 说明符时,它需要一个指向整数的指针作为参数,因此正确的方法是
if (scanf("%d", &arr[i].x) == 1)
/* succesful */
else
/* error */
*scanf() 系列函数无法匹配您想要的模式,要么使用正则表达式库,要么通过拆分 (value, value) 和它们的内容来解析字符串。
我想到的一种方法是将strtok() 与")," 一起使用,但这不会计算最后一个元素,如果")" 和"," 之间有空格,则很容易失败,所以,状态机并一次解析一个字符的字符串可能是最好的方法。
这是我的意思的一个例子,我喜欢写这个
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct point
{
int x;
int y;
};
struct stack
{
char *top;
char **stack;
size_t count;
size_t size;
};
void
stackinit(struct stack *stack)
{
if (stack == NULL)
return;
stack->top = NULL;
stack->stack = NULL;
stack->count = 0;
stack->size = 0;
}
void
stackfinish(struct stack *stack)
{
if (stack == NULL)
return;
free(stack->stack);
stack->stack = NULL;
}
char *
stacktop(struct stack *stack)
{
if ((stack == NULL) || (stack->count == 0))
return NULL;
return stack->stack[stack->count - 1];
}
void
stackpush(struct stack *stack, char *value)
{
void *pointer;
if (stack == NULL)
return;
if (stack->size == stack->count)
{
pointer = realloc(stack->stack, (stack->size + 100) * sizeof(char *));
if (pointer == NULL)
return;
stack->stack = pointer;
stack->size += 100;
}
if (stack->stack == NULL)
return;
stack->stack[stack->count] = value;
stack->count += 1;
}
void
stackpop(struct stack *stack)
{
if ((stack == NULL) || (stack->count <= 0))
return;
stack->count -= 1;
stack->stack[stack->count] = NULL;
}
void
extractpoint(char *string, struct point **points, size_t *count)
{
struct point point;
void *pointer;
char *tail;
if ((string == NULL) || (points == NULL) || (count == NULL))
return;
tail = strchr(string, ')');
if (tail == NULL)
return;
if (sscanf(string, "%d,%d", &point.x, &point.y) != 2)
return;
pointer = realloc(*points, (1 + count[0]) * sizeof(*points));
if (pointer == NULL)
return;
points[0] = pointer;
points[0][count[0]++] = point;
}
void
parse(char *input, struct point **points, size_t *count)
{
struct stack stack;
stackinit(&stack);
while (*(input++) != '\0')
{
char *top;
switch (*input)
{
case '(':
stackpush(&stack, input + 1);
break;
case ')':
stackpop(&stack);
break;
case ',':
top = stacktop(&stack);
if (top == NULL)
continue;
extractpoint(top, points, count);
break;
default:
break;
}
}
stackfinish(&stack);
return;
}
int
main(void)
{
char input[] = "((1828,299),((2729,2553),(2797,2929),(2200,1383),(2894,876))";
size_t count = 0;
struct point *points = NULL;
size_t index = 0;
parse(input, &points, &count);
for (index = 0 ; index < count ; ++index)
fprintf(stdout, "%zu: %d, %d\n", index, points[index].x, points[index].y);
free(points);
return 0;
}