2012-10-16 11 views
9

Các đầu vào bao gồm một chuỗi và một số nguyên, được phân cách bởi một '/', như thế này:sử dụng scanf để đọc một chuỗi và một int phân cách bằng/

hello/17 

Và tôi muốn đọc đầu vào thành một chuỗi và một số int, như sau:

char str[20]; 
int num; 
scanf("%s/%d", str, &num); // this how I tried to do it. 

Tôi dường như không thể làm điều đó, bất kỳ lời khuyên nào?

+0

Câu hỏi thú vị. 'scanf' có thể có một cái gì đó để mô phỏng phù hợp hơn với chỉ'% s'. – Eregrith

Trả lời

13

scanf đang chờ chuỗi kết thúc khoảng trắng khi nó cố gắng đọc %s.

Cố gắng xác định nhân vật cấm đặt trực tiếp:

scanf("%[^/]/%d", str, &num); 

Bạn có thể đọc thêm về các mã Formating here

+1

Cẩn thận, bạn đã gõ '% d' thay vì'% s' ở vị trí đầu tiên – Eregrith

7

Bạn chỉ cần chạy chương trình sau:

#include <stdio.h> 

int main (void) { 
    char str[20] = {'\0'}; 
    int count, num = 42; 

    count = sscanf ("hello/17", "%s/%d", str, &num); 

    printf ("String was '%s'\n", str); 
    printf ("Number was %d\n", num); 
    printf ("Count was %d\n", count); 

    return 0; 
} 

để xem tại sao điều này lại xảy ra. Đầu ra là:

String was 'hello/17' 
Number was 42 
Count was 1 

Lý do phải làm với định dạng số %s. Từ C99 7.19.6.2 The fscanf function (phần lớn không thay đổi trong C11, và nghiêng là của tôi):

s: phù hợp với một chuỗi các phi trắng-không gian ký tự.

Kể từ / không phải là khoảng trắng, nó được bao gồm trong chuỗi bit, cũng như các 17 với lý do tương tự. Điều đó cũng được chỉ ra bởi thực tế là sscanf trả về 1, có nghĩa là chỉ một mục được quét.

Những gì bạn sẽ tìm kiếm là nội dung quét bất kỳ ký tự nào khác hơn / thành chuỗi (bao gồm khoảng trắng). Cùng một phần của tiêu chuẩn cũng giúp ích:

[: khớp với chuỗi ký tự không phải là chuỗi ký tự mong muốn (bản quét). Trình chỉ định chuyển đổi bao gồm tất cả các ký tự tiếp theo trong chuỗi định dạng, tối đa và bao gồm dấu ngoặc vuông phù hợp (]). Các ký tự giữa các dấu ngoặc đơn (danh sách quét) soạn bản quét, trừ khi ký tự sau dấu ngoặc vuông trái là dấu mũ (^), trong trường hợp đó, bản quét có chứa tất cả các ký tự không xuất hiện trong danh sách quét giữa dấu mũ và khung bên phải.

Nói cách khác, một cái gì đó như:

#include <stdio.h> 
int main (void) { 
    char str[20] = {'\0'}; 
    int count, num = 42; 

    count = sscanf ("hello/17", "%[^/]/%d", str, &num); 

    printf ("String was '%s'\n", str); 
    printf ("Number was %d\n", num); 
    printf ("Count was %d\n", count); 

    return 0; 
} 

mang đến cho bạn:

String was 'hello' 
Number was 17 
Count was 2 

Một mảnh khác của lời khuyên: không bao giờ bao giờ sử dụng scanf với vô biên %s , bạn đang yêu cầu tấn công tràn bộ đệm. Nếu bạn muốn có chức năng nhập người dùng mạnh mẽ, hãy xem this answer.

Khi bạn có nó như một chuỗi, bạn có thể sscanf nó vào nội dung trái tim của bạn mà không đáng lo ngại về tràn bộ đệm (vì bạn đã giới hạn kích thước khi nhập).

+0

cảm ơn câu trả lời chi tiết của bạn. – Alcott