2014-09-29 15 views
5

Nếu một dòng không khớp với định dạng quét [fsv], thì bảo đảm scanf có không chạm vào các con trỏ được cung cấp không khớp không?Con trỏ sscanf có liên lạc không nếu không tìm thấy kết quả phù hợp?

Ví dụ, nếu

int int1 = 3; 
int int2 = 5; 
sscanf(line, "%d %d", &int1, &int2); 

trả về 0, được các số nguyên được bảo đảm là vẫn còn 3 và 5, hoặc có thể int1 đã được thay đổi?

+0

(Bản sao được tìm thấy bởi Blue Moon, bên dưới) –

Trả lời

5

Câu trả lời ngắn gọn là có, trong trường hợp của bạn, bạn có thể đảm bảo rằng int1int2 đã không thay đổi.

Tuy nhiên, tôi sẽ tham mưu chống dựa vào hành vi này, vì nó có khả năng để sản xuất mã đó là khó khăn để đọc - và bởi vì:


Câu trả lời dài là nó phụ thuộc vào chuỗi định dạng của bạn. Nhìn vào tiêu chuẩn C11 cho fscanf (s7.21.6.2.16), ta có:

Chức năng fscanf trả về giá trị của EOF vĩ mô nếu một thất bại đầu vào xảy ra trước khi chuyển đổi đầu tiên (nếu có) đã hoàn thành . Nếu không, hàm trả về số lượng các mục nhập được gán, có thể ít hơn số được cung cấp cho hoặc thậm chí là 0, trong sự kiện xảy ra lỗi sớm.

cực kỳ quan trọng là định nghĩa này các mặt hàng đầu vào từ sau này trong 7.21.6.2:

Một mục đầu vào được định nghĩa là chuỗi dài nhất của các nhân vật đầu vào mà không vượt quá bất kỳ chiều rộng lĩnh vực cụ thể và đó là hoặc là tiền tố của, một chuỗi đầu vào phù hợp

So. Số được trả về bởi scanf là số mục được đọc từ luồng, chứ không phải số con trỏ được ghi vào.

Ngoài ra có liên quan là 7.21.6.2.2:

Nếu định dạng được sử dụng hết trong khi tranh luận vẫn còn, thừa đối số được đánh giá (như mọi khi) nhưng nếu không thì bỏ qua.

Hành vi của phớt lờ lập luận rằng không được ghi vào cũng được làm rõ trong một ví dụ ở phần cuối của phần đó:

Trong:

#include <stdio.h> 
    /* ... */ 
    int d1, d2, n1, n2, i; 
    i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2); 

giá trị 123 là được gán cho d1 và giá trị 3 đến n1. Vì %n không bao giờ có thể bị lỗi đầu vào, giá trị của 3 cũng được gán cho n2. Giá trị của d2 không bị ảnh hưởng. Giá trị 1 được gán cho i.

Trong trường hợp bạn không quen thuộc với %n, đó là "số ký tự được đọc từ luồng cho đến thời điểm này".

Đây là một ví dụ tuyệt vời để minh họa câu hỏi của bạn - ở đây chúng tôi có ba con trỏ được viết tới và một con trỏ không bị ảnh hưởng. Tuy nhiên, fscanf chỉ trả lại 1 ở đây - vì nó chỉ gán một "mục nhập" từ luồng.

Vì vậy, trong ví dụ của bạn, có, nếu bạn đã có %d %d và bạn vượt qua nó cái gì đó gây ra 0 lần đọc, sau đó có, các con trỏ sẽ bị ảnh hưởng.

Nhưng nếu bạn có %n trong đó, thì hàm của bạn vẫn có thể trả về 0 hoặc EOF trong khi vẫn tiêu thụ một số đầu vào và ghi vào con trỏ. Ví dụ:

sscanf("aaa","aaa%n%d",&n1,&n2); 

này viết 3 để n1, lá n2 hoang sơ, và trả EOF. Và:

sscanf("aaa bbb","aaa%n%d",&n1,&n2); 

này viết 3 để n1, lá n2 hoang sơ, và trả về 0.

+1

Không rõ điều gì xảy ra trong trường hợp lỗi khớp. Đoạn trích được trích dẫn chỉ đảm bảo về các mục được quét thành công và không nói bất kỳ mục nào không được quét (con trỏ). Đặt nó theo cách này: * Nếu * "* scanf" chức năng không khởi tạo tất cả các con trỏ (giá trị) trước khi quét thực tế, nó vi phạm bất cứ điều gì trong tiêu chuẩn? –

+0

@BlueMoon nói lên những gì tôi nghĩ khi đặt câu hỏi. Tài liệu hoặc thông số có nói gì về điều này không? –

+0

Tôi đã chỉnh sửa câu trả lời để nêu rõ hơn những gì tiêu chuẩn nói. Và để thay đổi nội dung từ trước đó, không chính xác, câu trả lời của tôi :) –

0

Nên có ít nhất là nhiều trong số những lý lẽ như số lượng các giá trị được lưu trữ bởi sự xác định dạng của sscanf. Các đối số bổ sung được bỏ qua bởi hàm sscanf. Nếu dòng có chứa "10 20", thì int1 và int2 sẽ được thay đổi thành 10 và 20 tương ứng. Tuy nhiên, nếu dòng có chứa "aa bb", thì int1 và int2 sẽ được giữ lại tương ứng là 3 và 5.

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