2016-05-08 14 views
9

Tôi muốn sscanf một dòng và chắc chắn rằng không có gì nhiều hơn sau đó những gì tôi muốn trong đó. Mã này trông như thế này:Làm thế nào để sscanf để đảm bảo bộ đệm là chính xác những gì tôi muốn?

void parse_init_command(char *buffer, command *new_command) { 
    if (sscanf(buffer, 
     "%s %d %d %d %d %d %d %d\n", 
     new_command->name, 
     &new_command->data[0], 
     &new_command->data[1], 
     &new_command->data[2], 
     &new_command->data[3], 
     &new_command->data[4], 
     &new_command->data[5], 
     &new_command->data[6]) != 8) { 
     strncpy(new_command->name, "WRONG_INPUT", 15); 
    } 
} 

Khi tôi nhận được một đầu vào như:

INIT 9 11 3 1 1 1 9 

mọi thứ đều tốt, nhưng sau đó một đầu vào như thế này

INIT 9 11 3 1 1 1 9 s 

cũng được chấp nhận. Tôi nghĩ rằng nếu tôi thêm "\ n" mọi thứ sẽ hoạt động tốt, vì tôi biết rằng mọi dòng đầu vào đều kết thúc bằng một EOL, nhưng nó không thành công.

+3

'scanf' coi ký tự dòng mới là khoảng trắng, giống như các tab và dấu cách. Bạn có thể đọc giá trị giả thứ chín, một chuỗi ngắn với giá trị cực đại được thực thi. width ('% 2s') có lẽ, và bắt buộc rằng số lượng chuyển đổi không vượt quá 8. –

+0

Bộ đệm của bạn có được khởi tạo trước khi được chuyển vào hàm này không? – bentank

Trả lời

2

Một cái gì đó như thế này có thể làm điều đó nếu đầu vào của bạn luôn có một dòng mới ở cuối. Mã yêu cầu thêm char loại và kiểm tra xem đó là \n, cũng như số lượng chính xác của các mục được quét. Nó in 1 để thành công - một biến thể nhỏ cho chức năng của bạn cho mục đích của ví dụ này.

#include <stdio.h> 

typedef struct { 
    char name[100]; 
    int data[7]; 
} command; 

int parse_init_command(char *buffer, command *new_command) { 
    char eol = 0; 
    int num = sscanf(buffer, "%s%d%d%d%d%d%d%d%c", 
           new_command->name, 
           &new_command->data[0], 
           &new_command->data[1], 
           &new_command->data[2], 
           &new_command->data[3], 
           &new_command->data[4], 
           &new_command->data[5], 
           &new_command->data[6], 
           &eol); 
    return num == 9 && eol == '\n'; 
} 

int main(void) 
{ 
    char inp[50]; 
    command rec; 
    fgets(inp, sizeof inp, stdin); 
    printf("%d\n", parse_init_command(inp, &rec)); 
    return 0; 
} 

phiên Chương trình từ bàn phím:

INIT 9 11 3 1 1 1 9 
1 

INIT 9 11 3 1 1 1 9 s 
0 

Lưu ý không có không gian hàng đầu trước khi %c đó sẽ gây ra khoảng trắng để được bỏ qua, đánh bại các điểm có nó.

+2

Điều đó sẽ tạo ra một lỗi khó giải thích khi người dùng gõ 'INIT 9 11 3 1 1 1 9' (với một khoảng trống ở cuối.) Tôi thích giải pháp của @ MOehm tốt hơn (trong một bình luận cho OP). – rici

Các vấn đề liên quan