[英]read comma separated values from brackets with scanf()
我有以下輸入:
((1828,299),(2729,2553),(2797,2929),(2200,1383),(2894,876))
和以下結構:
struct x{
int a;
int b;
}
如何使用scanf()讀取輸入以創建結構數組?
我努力了
scanf("%[^, ()],%d", &arr);
if (i % 2 == 0){
arr[i].x = scanf("%d");
}else
arr[i].y = scanf("%d");
但是當我嘗試打印這些值時,我得到了一些奇怪的字符
錯誤使用scanf()
scanf("%[^, ()],%d", ...)
希望掃描並形成字符串( "%[^, ()]"
)和int
( "%d"
)。 代碼僅用於保存int
。
代碼沒有檢查表單scanf()
的返回值,因此如果不知道任何掃描問題,則代碼。
當數據為一行時 ,建議使用fgets()
, 然后對其進行解析。 可以使用strtok() strtol() sscanf()
。 每個都有各種優點/缺點。 例:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXN (5)
// maximum size needed to print and `int`
#define INTSIZE (sizeof (int )* CHAR_BIT / 3 + 3)
// Expect buffer size needed
#define EXPECTEDSIZE (1+(2*INTSIZE + 4) + 3)
void fooo() {
int i;
struct x {
int a;
int b;
} xx[MAXN];
char buf[EXPECTEDSIZE * 2]; // I favor 2x size buffers
while (fgets(buf, sizeof buf, stdin)) {
char *p = buf;
if (*p++ != '(') {
exit(EXIT_FAILURE);
}
for (i = 0; i < MAXN; i++) {
int n; // use %n to locate scan completion
int cnt = sscanf(p, " (%d ,%d ) %n", &xx[i].a, &xx[i].b, &n);
fprintf(stderr, "cnt = %d '%s'\n", cnt, p);
if (cnt != 2) {
exit(EXIT_FAILURE);
}
p += n;
if (p[0] != ',') {
if (p[0] == ')') {
i++;
break; // Successfully reached the end
}
exit(EXIT_FAILURE);
}
p++;
}
int j;
for (j=0; j< i; j++) {
printf("%d (%d ,%d )\n", j, xx[j].a, xx[j].b);
}
}
}
出現奇怪字符的原因是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;
}
#include <stdio.h>
#include <stdlib.h>
struct x{
int a;
int b;
};
int count(const char *s){
if(s == NULL || *s != '(')
return 0;//bad
int n, a, b, count = 0;
for(;;){
n = -1;
if(2!=sscanf(++s, "(%d,%d)%n", &a, &b, &n) || n < 0){
return 0;
} else {
s += n;
++count;
if(*s == ',')
continue;
else if(*s == ')')
return count;
else
return 0;
}
}
}
void set(struct x *a, const char *s){
int n, c = 0;
while(2==sscanf(++s, "(%d,%d)%n", &a[c].a, &a[c].b, &n)){
s += n;
++c;
}
}
int main(void) {
char *input = "((1828,299),(2729,2553),(2797,2929),(2200,1383),(2894,876))";
int i, n = count(input);
if(n == 0){
printf("invalid format!\n");
exit(EXIT_FAILURE);
}
struct x arr[n];
set(arr, input);
for(i = 0; i < n; ++i){
printf("(%4d, %4d)\n", arr[i].a, arr[i].b);
}
return 0;;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.