Skip to content

📥📤 Nhập xuất dữ liệu trong C++

📖 Giới thiệu

Nhập xuất dữ liệu (Input/Output - I/O) là cách chương trình giao tiếp với người dùng và môi trường bên ngoài. Đây là một trong những kỹ năng cơ bản nhất trong lập trình - làm sao để chương trình có thể nhận thông tin từ người dùng và hiển thị kết quả.

C++ cung cấp nhiều cách để thực hiện I/O: từ các phương thức hiện đại như cin/cout đến các hàm truyền thống như printf/scanf từ C. Mỗi phương pháp có ưu nhược điểm riêng và phù hợp với những tình huống khác nhau.

Trong bài này, chúng ta sẽ học cách sử dụng cin/cout hiệu quả, xử lý các vấn đề thường gặp, và tìm hiểu về định dạng đầu ra đẹp mắt.

🔧 Cú pháp

Xuất dữ liệu với cout

cpp
#include <iostream>
using namespace std;

// Xuất cơ bản
cout << "Hello World!";                    // Xuất chuỗi
cout << 42;                               // Xuất số
cout << variable;                         // Xuất biến

// Xuất nhiều giá trị
cout << "Tuổi: " << age << " năm" << endl;

// Điều khiển định dạng
cout << endl;                             // Xuống dòng
cout << "\n";                             // Xuống dòng (escape sequence)
cout << "\t";                             // Tab
cout << flush;                            // Xóa buffer

Nhập dữ liệu với cin

cpp
#include <iostream>
using namespace std;

int number;
string name;
double price;

// Nhập cơ bản
cin >> number;                            // Nhập số nguyên
cin >> name;                              // Nhập string (một từ)
cin >> price;                             // Nhập số thực

// Nhập nhiều giá trị
cin >> a >> b >> c;                       // Nhập 3 giá trị cùng lúc

// Nhập chuỗi có khoảng trắng
getline(cin, fullName);                   // Nhập cả dòng

Định dạng đầu ra với manipulators

cpp
#include <iostream>
#include <iomanip>
using namespace std;

double pi = 3.14159265;

cout << fixed;                            // Định dạng số thực cố định
cout << setprecision(2);                  // 2 chữ số thập phân
cout << pi;                               // Output: 3.14

cout << setw(10);                         // Độ rộng 10 ký tự
cout << left;                             // Căn trái
cout << "Hello";                          // "Hello     "

Printf và scanf (C-style)

cpp
#include <cstdio>

int age;
double height;
char name[50];

// Printf - định dạng linh hoạt
printf("Tuổi: %d\n", age);               // %d cho int
printf("Chiều cao: %.2f cm\n", height);  // %.2f cho double với 2 số thập phân
printf("Tên: %s\n", name);               // %s cho string

// Scanf - nhập có định dạng
scanf("%d", &age);                        // Nhập int
scanf("%lf", &height);                   // Nhập double
scanf("%s", name);                       // Nhập string

🔬 Phân tích & Giải thích chi tiết

Cin vs Getline

Cin chỉ đọc đến khoảng trắng đầu tiên:

cpp
string firstName;
cin >> firstName;        // Nhập "Nguyen Van" → chỉ lấy "Nguyen"

Getline đọc cả dòng:

cpp
string fullName;
getline(cin, fullName);  // Nhập "Nguyen Van A" → lấy toàn bộ

Buffer và vấn đề thường gặp

Vấn đề mixing cin và getline:

cpp
int age;
string name;

cin >> age;              // Nhập 25 và nhấn Enter
getline(cin, name);      // Lấy ký tự xuống dòng → name = ""

// Giải pháp:
cin >> age;
cin.ignore();            // Bỏ qua ký tự xuống dòng
getline(cin, name);      // Bây giờ mới lấy tên

Kiểm tra lỗi nhập liệu

cpp
int number;
cout << "Nhập số: ";

if (cin >> number) {
    cout << "Nhập thành công: " << number << endl;
} else {
    cout << "Lỗi: Không phải số!" << endl;
    cin.clear();          // Xóa flag lỗi
    cin.ignore(1000, '\n'); // Bỏ qua input sai
}

So sánh cin/cout vs printf/scanf

Đặc điểmcin/coutprintf/scanf
Type safetyAn toàn kiểuKhông an toàn
Tốc độChậm hơnNhanh hơn
Định dạngKhó hơnDễ và linh hoạt
Đơn giảnDễ sử dụngPhức tạp hơn
C++ styleModernLegacy

Tối ưu hóa I/O

cpp
// Tăng tốc độ I/O cho competitive programming
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);

💻 Ví dụ minh họa

Chương trình nhập thông tin cá nhân

cpp
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

int main() {
    string fullName, address;
    int age;
    double height, weight;
    char gender;
    
    cout << "=== ĐĂNG KÝ THÔNG TIN CÁ NHÂN ===" << endl;
    
    // Nhập họ tên (có khoảng trắng)
    cout << "Họ và tên: ";
    getline(cin, fullName);
    
    // Nhập tuổi
    cout << "Tuổi: ";
    cin >> age;
    
    // Nhập giới tính
    cout << "Giới tính (M/F): ";
    cin >> gender;
    
    // Nhập chiều cao và cân nặng
    cout << "Chiều cao (cm): ";
    cin >> height;
    cout << "Cân nặng (kg): ";
    cin >> weight;
    
    // Xóa buffer trước khi dùng getline
    cin.ignore();
    
    // Nhập địa chỉ
    cout << "Địa chỉ: ";
    getline(cin, address);
    
    // Tính BMI
    double bmi = weight / ((height/100) * (height/100));
    
    // Hiển thị thông tin với định dạng đẹp
    cout << "\n" << string(40, '=') << endl;
    cout << "         THÔNG TIN CÁ NHÂN" << endl;
    cout << string(40, '=') << endl;
    
    cout << left;  // Căn trái
    cout << setw(15) << "Họ tên:" << fullName << endl;
    cout << setw(15) << "Tuổi:" << age << " tuổi" << endl;
    cout << setw(15) << "Giới tính:" << (gender == 'M' ? "Nam" : "Nữ") << endl;
    cout << setw(15) << "Chiều cao:" << height << " cm" << endl;
    cout << setw(15) << "Cân nặng:" << weight << " kg" << endl;
    cout << setw(15) << "BMI:" << fixed << setprecision(1) << bmi << endl;
    cout << setw(15) << "Địa chỉ:" << address << endl;
    
    return 0;
}

Kết quả chạy:

=== ĐĂNG KÝ THÔNG TIN CÁ NHÂN ===
Họ và tên: Nguyễn Văn A
Tuổi: 25
Giới tính (M/F): M
Chiều cao (cm): 175
Cân nặng (kg): 70
Địa chỉ: 123 Đường ABC, Quận 1, TP.HCM

========================================
         THÔNG TIN CÁ NHÂN
========================================
Họ tên:        Nguyễn Văn A
Tuổi:          25 tuổi
Giới tính:     Nam
Chiều cao:     175 cm
Cân nặng:      70 kg
BMI:           22.9
Địa chỉ:       123 Đường ABC, Quận 1, TP.HCM

Chương trình in bảng nhân

cpp
#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    int number;
    
    cout << "Nhập số để in bảng nhân: ";
    cin >> number;
    
    cout << "\n" << string(30, '=') << endl;
    cout << "    BẢNG NHÂN " << number << endl;
    cout << string(30, '=') << endl;
    
    for (int i = 1; i <= 10; i++) {
        cout << setw(2) << number << " x " 
             << setw(2) << i << " = " 
             << setw(3) << (number * i) << endl;
    }
    
    return 0;
}

Chương trình xử lý lỗi nhập liệu

cpp
#include <iostream>
#include <limits>
using namespace std;

int main() {
    int number;
    
    cout << "=== DEMO XỬ LÝ LỖI NHẬP LIỆU ===" << endl;
    
    while (true) {
        cout << "Nhập một số nguyên (1-100): ";
        
        if (cin >> number) {
            // Nhập thành công, kiểm tra phạm vi
            if (number >= 1 && number <= 100) {
                cout << "Bạn đã nhập: " << number << endl;
                break;  // Thoát vòng lặp
            } else {
                cout << "Lỗi: Số phải trong khoảng 1-100!" << endl;
            }
        } else {
            // Nhập thất bại (không phải số)
            cout << "Lỗi: Vui lòng nhập số nguyên!" << endl;
            
            // Xóa cờ lỗi và buffer
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }
    }
    
    cout << "Cảm ơn bạn đã nhập đúng!" << endl;
    
    return 0;
}

So sánh cin/cout vs printf/scanf

cpp
#include <iostream>
#include <iomanip>
#include <cstdio>
using namespace std;

int main() {
    int age = 25;
    double height = 175.5;
    string name = "Nguyen Van A";
    
    cout << "=== DEMO CIN/COUT VS PRINTF/SCANF ===" << endl;
    
    // Cách 1: cout với manipulators
    cout << "\n1. Sử dụng cout:" << endl;
    cout << "Tên: " << name << endl;
    cout << "Tuổi: " << age << " tuổi" << endl;
    cout << "Chiều cao: " << fixed << setprecision(1) << height << " cm" << endl;
    
    // Cách 2: printf
    cout << "\n2. Sử dụng printf:" << endl;
    printf("Tên: %s\n", name.c_str());
    printf("Tuổi: %d tuổi\n", age);
    printf("Chiều cao: %.1f cm\n", height);
    
    // Demo định dạng phức tạp với printf
    cout << "\n3. Định dạng phức tạp với printf:" << endl;
    printf("%-15s %3d tuổi %6.1f cm\n", name.c_str(), age, height);
    printf("|%-10s|%5d|%8.2f|\n", "Tên", age, height);
    
    // Demo định dạng với cout
    cout << "\n4. Định dạng với cout:" << endl;
    cout << left << setw(15) << name 
         << right << setw(3) << age << " tuổi "
         << setw(6) << fixed << setprecision(1) << height << " cm" << endl;
    
    return 0;
}

🏋️ Thực hành

Bài tập 1: Máy tính tiền điện

Viết chương trình tính tiền điện:

  • Nhập số kWh tiêu thụ
  • Bậc 1 (0-50 kWh): 1,678 VNĐ/kWh
  • Bậc 2 (51-100 kWh): 1,734 VNĐ/kWh
  • Bậc 3 (101-200 kWh): 2,014 VNĐ/kWh
  • Bậc 4 (201+ kWh): 2,536 VNĐ/kWh

Bài tập 2: Formatter numbers

Viết chương trình nhập một số thực và hiển thị theo nhiều định dạng:

  • Số gốc
  • 2 chữ số thập phân
  • Dạng khoa học (scientific notation)
  • Căn phải trong 15 ký tự

Bài tập 3: Input validation

Viết hàm nhập tuổi với validation:

  • Phải là số nguyên
  • Trong khoảng 1-120
  • Cho phép nhập lại nếu sai

Bài tập 4: File simulation

Viết chương trình "giả lập" đọc file:

  • Nhập nhiều dòng text (kết thúc bằng "END")
  • Đếm số dòng, số từ, số ký tự
  • Hiển thị thống kê

Lời giải chi tiết

Bài tập 1:

cpp
#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    double kwh;
    cout << "Nhập số kWh tiêu thụ: ";
    cin >> kwh;
    
    double total = 0;
    
    if (kwh <= 50) {
        total = kwh * 1678;
    } else if (kwh <= 100) {
        total = 50 * 1678 + (kwh - 50) * 1734;
    } else if (kwh <= 200) {
        total = 50 * 1678 + 50 * 1734 + (kwh - 100) * 2014;
    } else {
        total = 50 * 1678 + 50 * 1734 + 100 * 2014 + (kwh - 200) * 2536;
    }
    
    cout << "Tiền điện: " << fixed << setprecision(0) << total << " VNĐ" << endl;
    
    return 0;
}

Bài tập 2:

cpp
#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    double number;
    cout << "Nhập số thực: ";
    cin >> number;
    
    cout << "\nCác định dạng khác nhau:" << endl;
    cout << "Số gốc: " << number << endl;
    cout << "2 chữ số TP: " << fixed << setprecision(2) << number << endl;
    cout << "Khoa học: " << scientific << number << endl;
    cout << "Căn phải 15: " << fixed << setw(15) << number << endl;
    
    return 0;
}

Bài tập 3:

cpp
#include <iostream>
#include <limits>
using namespace std;

int inputAge() {
    int age;
    while (true) {
        cout << "Nhập tuổi (1-120): ";
        if (cin >> age && age >= 1 && age <= 120) {
            return age;
        } else {
            cout << "Lỗi! Vui lòng nhập số từ 1-120." << endl;
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
        }
    }
}

int main() {
    int age = inputAge();
    cout << "Tuổi hợp lệ: " << age << endl;
    return 0;
}

📋 Tóm tắt

🎯 Những gì đã học

  • cout: Xuất dữ liệu với toán tử <<
  • cin: Nhập dữ liệu với toán tử >>
  • getline(): Nhập chuỗi có khoảng trắng
  • Manipulators: setw(), setprecision(), fixed, left, right
  • Error handling: Kiểm tra và xử lý lỗi nhập liệu

🔧 Best Practices

  • Dùng getline() cho chuỗi có khoảng trắng
  • Luôn kiểm tra tính hợp lệ của input
  • Sử dụng cin.ignore() khi mix cin và getline
  • Định dạng output cho dễ đọc
  • Xử lý lỗi nhập liệu một cách graceful

🚀 Chuẩn bị cho bước tiếp theo

Bài học tiếp theo sẽ tìm hiểu về cấu trúc điều khiển (if, switch). Đảm bảo bạn đã:

  • [x] Thành thạo cin/cout cơ bản
  • [x] Biết cách nhập chuỗi có khoảng trắng
  • [x] Sử dụng được manipulators để định dạng
  • [x] Xử lý được lỗi nhập liệu

💡 Lời khuyên

"Input validation là rất quan trọng! Luôn giả định rằng người dùng sẽ nhập sai để viết code robust hơn."


Chuyển sang: Cấu trúc điều khiển để học về if, else, switch-case!

Khóa học C++ miễn phí