Cin.Ignore Là Gì ? (Phần 2) C++ — Khi Nào Và Tại Sao Tôi Cần Sử Dụng Cin

Tôi đã viết một chương trình rất cơ bản trong C++, yêu cầu người dùng nhập một số và sau đó là một chuỗi. Thật ngạc nhiên, khi chạy chương trình, nó không bao giờ dừng lại để yêu cầu chuỗi. Nó chỉ bỏ qua nó. Sau khi đọc một số bài trên StackOverflow, tôi phát hiện ra rằng tôi cần thêm một dòng có nội dung:

cin.ignore(256, “\n”);trước dòng nhận được đầu vào chuỗi. Thêm vào đó đã khắc phục vấn đề và làm cho chương trình hoạt động. Câu hỏi của tôi là tại sao C++ cần dòng cin.ignore() này và làm cách nào tôi có thể dự đoán khi nào tôi sẽ cần sử dụng cin.ignore()?

Đây là chương trình tôi đã viết:

#include #include using namespace std;int main(){ double num; string mystr; cout > num; cout
c++cingetlineignore
45
24 thg 8, 2014Raddicus
Bỏ qua là chính xác những gì tên gọi ngụ ý.

Bạn đang xem: Cin.ignore là gì

Nó không “vứt bỏ” thứ gì đó bạn không cần thay vào đó, nó bỏ qua số lượng ký tự bạn chỉ định khi bạn gọi nó, cho đến ký tự bạn chỉ định làm điểm dừng.

Nó hoạt động với cả bộ đệm đầu vào và đầu ra.

Về cơ bản, đối với std::cin các câu lệnh bạn sử dụng bỏ qua trước khi bạn thực hiện cuộc gọi getline, bởi vì khi người dùng nhập nội dung nào đó bằng std::cin, họ nhấn enter và một “\n” char vào bộ đệm cin. Sau đó, nếu bạn sử dụng getline, nó sẽ nhận được char dòng mới thay vì chuỗi bạn muốn. Vì vậy, bạn thực hiện một std::cin.ignore(1000,”\n”) và điều đó sẽ xóa bộ đệm theo chuỗi mà bạn muốn. (1000 được đặt ở đó để bỏ qua một số ký tự cụ thể trước điểm ngắt được chỉ định, trong trường hợp này là ký tự dòng mới\n.)

42
24 thg 8, 2014savageWays
Bạn đang nghĩ về điều này sai cách. Bạn đang suy nghĩ theo các bước hợp lý mỗi lần cin hoặc getline được sử dụng. Ví dụ. Đầu tiên yêu cầu một số, sau đó yêu cầu một tên. Đó là cách nghĩ sai về cin. Vì vậy, bạn chạy vào một điều kiện cuộc đua bởi vì bạn cho rằng luồng rõ ràng mỗi khi bạn yêu cầu đầu vào.

Nếu bạn viết chương trình của bạn hoàn toàn cho đầu vào, bạn sẽ thấy vấn đề:

_void main(void){ double num; string mystr; cin >> num; getline(cin, mystr); cout _Ở trên, bạn đang nghĩ, “đầu tiên hãy lấy một con số.” Vì vậy, bạn nhập _123_ nhấn enter và đầu ra của bạn sẽ là _num=123,mystr=””_. Tại sao vậy? Đó là bởi vì trong luồng bạn có _123\n_ và _123_ được phân tích cú pháp vào biến num trong khi _\n_ vẫn ở trong luồng. Đọc tài liệu cho hàm getline theo mặc định, nó sẽ tìm trong istream cho đến khi gặp _\n_. Trong ví dụ này, vì _\n_ nằm trong luồng, có vẻ như nó “bỏ qua” nó nhưng nó hoạt động đúng.

Để các công việc trên hoạt động, bạn sẽ phải nhập _123Hello World_ sẽ xuất đúng _num=123,mystr=”Hello World”_. Điều đó hoặc bạn đặt _cin.ignore_ giữa cin và getline để nó sẽ chia thành các bước hợp lý mà bạn mong đợi.

Đây là lý do tại sao bạn cần lệnh ignore. Bởi vì bạn đang nghĩ về nó trong các bước hợp lý hơn là ở dạng luồng để bạn chạy vào điều kiện cuộc đua.

Lấy một ví dụ mã khác thường thấy trong các trường học:

_void main(void){ int age; string firstName; string lastName; cout > firstName; cout > lastName; cout > age; cout _Ở trên dường như là trong các bước hợp lý. Đầu tiên hỏi tên, họ, sau đó tuổi. Vì vậy, nếu bạn đã nhập John, sau đó nhập Doe, sau đó nhập _19_, ứng dụng sẽ hoạt động theo từng bước logic. Nếu bạn nghĩ về nó trong “luồng”, bạn chỉ cần nhập _John Doe 19_ vào câu hỏi “Tên:” và nó sẽ hoạt động tốt và xuất hiện để bỏ qua các câu hỏi còn lại. Để các bước trên hoạt động theo các bước logic, bạn sẽ cần ignore luồng còn lại cho mỗi lần ngắt logic trong các câu hỏi.

Chỉ cần nhớ nghĩ về đầu vào chương trình của bạn vì nó đang đọc từ một “luồng” và không theo các bước hợp lý. Mỗi lần bạn gọi cin nó sẽ được đọc từ một luồng. Điều này tạo ra một ứng dụng khá lỗi nếu người dùng nhập sai. Ví dụ: nếu bạn đã nhập một ký tự có dự kiến ​​_cin >> double_, ứng dụng sẽ tạo ra một đầu ra khá kỳ quái (dường như).

Xem thêm: Stay Focused Là Gì ? 3 Ứng Dụng Thú Vị Có Thể Giúp Bạn

Câu trả lời ngắn

Tại sao? Bởi vì vẫn còn khoảng trắng (trả về vận chuyển, tab, dấu cách, dòng mới) còn lại trong luồng đầu vào.

Khi nào? Khi bạn đang sử dụng một số chức năng không tự mình bỏ qua các khoảng trắng hàng đầu. Cin theo mặc định bỏ qua và loại bỏ khoảng trắng hàng đầu nhưng getline không tự bỏ qua khoảng trắng hàng đầu.

Bây giờ là câu trả lời chi tiết.

Tất cả mọi thứ bạn nhập trong bảng điều khiển được đọc từ luồng chuẩn stdin. Khi bạn nhập nội dung nào đó, giả sử 256 trong trường hợp của bạn và nhấn enter, nội dung của luồng sẽ trở thành 256\n. Bây giờ cin chọn 256 và xóa nó khỏi luồng và \n vẫn còn trong luồng. Bây giờ tiếp theo khi bạn nhập tên của mình, hãy nói Raddicus, nội dung mới của luồng là \nRaddicus.

Bây giờ đến đây bắt Khi bạn cố đọc một dòng bằng cách sử dụng getline, nếu không được cung cấp bất kỳ dấu phân cách nào làm đối số thứ ba, getline theo mặc định sẽ đọc cho đến ký tự dòng mới và xóa ký tự dòng mới khỏi luồng. Vì vậy, khi gọi dòng mới, getline đọc và loại bỏ \n khỏi luồng và dẫn đến một chuỗi trống được đọc trong mystr có vẻ như bị bỏ qua (nhưng không phải) vì đã có một dòng mới trong luồng, getline sẽ không nhắc nhở đầu vào vì nó đã đọc những gì đáng lẽ phải đọc.

Bây giờ, cin.ignore giúp ở đây như thế nào?

Theo trích xuất tài liệu bỏ qua từ cplusplus.com –

iux & bỏ qua (streamize n = 1, int delim = EOF); ​​

Trích xuất các ký tự từ chuỗi đầu vào và loại bỏ chúng, cho đến khi n ký tự được trích xuất hoặc một ký tự so sánh bằng dấu phân cách.

Hàm này cũng dừng trích xuất các ký tự nếu đạt đến cuối tệp. Nếu điều này đạt được sớm (trước khi trích xuất n ký tự hoặc tìm delim), hàm sẽ đặt cờ eofbit.

Vì vậy, cin.ignore(256, “\n”);, bỏ qua 256 ký tự đầu tiên hoặc tất cả các ký tự cho đến khi nó gặp phải phân định (ở đây\n trong trường hợp của bạn), tùy theo điều kiện nào đến trước (ở đây\n là ký tự đầu tiên, vì vậy nó sẽ bỏ qua cho đến khi gặp phải\n) .

Chỉ để bạn tham khảo, Nếu bạn không biết chính xác có bao nhiêu ký tự bỏ qua và mục đích duy nhất của bạn là xóa luồng để chuẩn bị đọc chuỗi bằng getline hoặc cin, bạn nên sử dụng cin.ignore(numeric_limits::max(),”\n”).

Xem thêm: Quark Là Gì – 7 Sự Thật Kì Lạ Về Các Quark

Giải thích nhanh: Nó bỏ qua các ký tự có kích thước tối đa của luồng hoặc cho đến khi gặp phải “\ n”, trường hợp nào xảy ra trước.

Sử dụng getline (cin, s) sau cin

Sử dụng getline (cin, s) sau cin

:: max (), “\ n”)” data-cat=”related-question”>cin.ignore (num_limits :: max (), “\ n”)

Đọc getline từ cin thành một chuỗi (C++)

sự biến thái của họ cin.get () và cin.getline ()

Tại sao đọc các dòng từ stdin trong C++ chậm hơn nhiều so với Python?

Kiểm tra luồng đầu vào cin tạo ra một số nguyên

Có nên đọc tiêu cực thành không dấu thông qua std :: cin (gcc, clang không đồng ý)?

C++ làm thế nào để đọc một dòng với dấu phân cách cho đến cuối mỗi dòng?

c ++ getline () không chờ nhập từ bảng điều khiển khi được gọi nhiều lần

getline () không hoạt động nếu được sử dụng sau một số đầu vào

Tôi có thể sử dụng 2 hoặc nhiều dấu phân cách trong getline chức năng C++ không?

Tại sao nhanh hơn để xử lý một mảng được sắp xếp hơn một mảng chưa được sắp xếp?

Hướng dẫn và danh sách sách C++ lưu khoát

” trong C++ là gì?” data-cat=”related-question”>Toán tử “->” trong C++ là gì?

Cách dễ nhất để chuyển đổi int thành chuỗi trong C++

Các quy tắc và thành ngữ cơ bản cho quá tải toán tử là gì?

Các tính năng mới trong C++ 17 là gì?

Ảnh hưởng của “C” bên ngoài trong C++ là gì?

Biểu thức lambda trong C++ 11 là gì?

Ngủ trong một phần nghìn giây