C++: الإدخال والإخراج بعمق

آخر تحديث: 2026-08-26

في الدرس 03 استخدمنا cin وcout باختصار، لكن هذا كان مجرد قمة الجبل الجليدي.

في السيناريوهات الواقعية، تحتاج للتعامل مع سلاسل نصية تحتوي مسافات، والتحكم في المنازل العشرية، وجعل الإخراج أكثر جمالًا...

في هذا الدرس، سنتعمق في جميع إمكانيات cin وcout.


1. الاستخدام المتقدم لـ cout

(1) 1.1 أحرف الهروب

بعض الأحرف لا يمكن كتابتها مباشرة (مثل سطر جديد، Tab)، لذا يجب تمثيلها باستخدام أحرف الهروب.

حرف الهروب المعنى المثال
\n سطر جديد std::cout << "Hello\nWorld";
\t Tab std::cout << "Name:\tMOTO";
\\ شرطة مائلة خلفية std::cout << "C:\\Users\\MOTO";
\" علامة اقتباس مزدوجة std::cout << "He said \"Hi\"";
\0 حرف فارغ (منهي السلسلة) (ستُغطى لاحقًا)

مثال: إخراج منسق بأحرف الهروب (صعوبة ⭐)

▶ مثال 2: تطبيق برمجي أساسي (صعوبة ⭐)

TEXT 📖 للعرض فقط
#include <iostream>

int main() {
 std::cout << "========== Report Card ==========\n";
 std::cout << "Name: \tMOTO\n";
 std::cout << "Age: \t35\n";
 std::cout << "Score: \t92.5\n";
 std::cout << "===================\n";
 
 return 0;
}

الخرج:

TEXT 📖 للعرض فقط
========== Report Card ==========

Name: 	MOTO

Age: 	35

Score: 	92.5

===================

(2) 1.2 endl مقابل \n

التدوين التأثير الأداء
std::endl يُخرج سطر جديد + يفرغ المخزن بطيء (يفرغ في كل مرة)
"\n" يُخرج سطر جديد فقط سريع (موصى به)

💡 توصية: ما لم تكن بحاجة صريحة لتفريغ المخزن، استخدم "\n" بدلًا من std::endl.

CPP
std::cout << "Hello" << std::endl; // Newline + flush (slow)
std::cout << "Hello\n"; // Newline only (fast, recommended)


2. الإخراج المنسق بـ cout

(1) 2.1 التحكم في المنازل العشرية

بشكل افتراضي، يختار cout التنسيق تلقائيًا لإخراج أعداد الفاصلة العائمة (مثل 3.14159 أو 3.14). لكن أحيانًا تحتاج عددًا ثابتًا من المنازل العشرية (مثل عرض سعر مثل $19.99).

يتطلب #include <iomanip>

TEXT 📖 للعرض فقط
#include <iostream>
#include <iomanip> // Must include this header

int main() {
 double pi = 3.141592653589793;
 
 std::cout << "Default: " << pi << std::endl;
 
 // Fixed decimal places (2 digits)
 std::cout << std::fixed << std::setprecision(2);
 std::cout << "2 decimal places: " << pi << std::endl;
 
 // Restore default
 std::cout.unsetf(std::ios::fixed);
 std::cout << std::setprecision(6); // Restore default precision
 std::cout << "Restored default: " << pi << std::endl;
 
 return 0;
}

💡 نقاط مهمة:

(2) 2.2 التحكم في عرض الإخراج (المحاذاة)

CPP
#include <iostream>
#include <iomanip>

int main() {
 std::cout << std::left; // Left-align
 std::cout << std::setw(10) << "Name" << std::setw(5) << "Age" << std::endl;
 std::cout << std::setw(10) << "MOTO" << std::setw(5) << 35 << std::endl;
 std::cout << std::setw(10) << "Alice" << std::setw(5) << 20 << std::endl;
 
 return 0;
}
المعالج التأثير
std::setw(n) تعيين عرض الإخراج التالي إلى n حرفًا
std::left محاذاة لليسار
std::right محاذاة لليمين (افتراضي)
std::setfill(c) تعيين حرف الملء (الافتراضي مسافة)


3. الاستخدام المتقدم لـ cin

(1) 3.1 فخ cin: يتوقف عند المسافات

cin >> يتوقف عن قراءة سلسلة نصية عندما يصادف مسافة!

TEXT 📖 للعرض فقط
#include <iostream>
#include <string>

int main() {
 std::string name;
 std::cout << "Please enter your full name (e.g., John Smith): ";
 std::cin >> name;
 std::cout << "Hello," << name << "!" << std::endl;
 return 0;
}

نتيجة التشغيل:

TEXT 📖 للعرض فقط
Please enter your full name (e.g., John Smith): John Smith
Hello,John! ← Only read "John", "Smith" was discarded

(2) 3.2 استخدام getline لقراءة سطر كامل

لقراءة سطر كامل بما فيه المسافات، استخدم std::getline().

CPP
#include <iostream>
#include <string>

int main() {
 std::string fullName;
 std::cout << "Please enter your full name: ";
 std::getline(std::cin, fullName); // Read entire line (including spaces)
 std::cout << "Hello," << fullName << "!" << std::endl;
 return 0;
}

نتيجة التشغيل:

TEXT 📖 للعرض فقط
Please enter your full name: John Smith
Hello,John Smith! ← Complete read

(3) 3.3 فخ المزج بين cin وgetline

المشكلة:

TEXT 📖 للعرض فقط
#include <iostream>
#include <string>

int main() {
 int age;
 std::string name;
 
 std::cout << "Please enter your age: ";
 std::cin >> age;
 
 std::cout << "Please enter your name: ";
 std::getline(std::cin, name); // ❌ This line gets skipped!
 
 std::cout << "Age: " << age << ",Name: " << name << std::endl;
 return 0;
}

السبب: بعد أن يقرأ cin >> age العدد الصحيح، يتبقى حرف سطر جديد \n في مخزن الإدخال. عندما يرى getline الحرف \n، يظن أن المستخدم أدخل سطرًا فارغًا ويعود فورًا.

الحل: استخدم cin.ignore() لتجاهل حرف السطر الجديد

CPP
#include <iostream>
#include <string>

int main() {
 int age;
 std::string name;
 
 std::cout << "Please enter your age: ";
 std::cin >> age;
 
 std::cin.ignore(); // Discard the newline character
 
 std::cout << "Please enter your name: ";
 std::getline(std::cin, name); // ✅ Now it reads correctly
 
 std::cout << "Age: " << age << ",Name: " << name << std::endl;
 return 0;
}

💡 القاعدة الذهبية: إذا استخدمت cin >> أولًا ثم getline، تذكر إضافة cin.ignore().



4. تطبيق: نموذج تسجيل معلومات المستخدم

▶ مثال 1: تسجيل معلومات المستخدم (صعوبة ⭐⭐)

TEXT 📖 للعرض فقط
#include <iostream>
#include <string>
#include <iomanip>

int main() {
 std::string name, address;
 int age;
 double salary;
 
 std::cout << "========== User Information Registration ==========\n";
 
 std::cout << "Please enter your name: ";
 std::getline(std::cin, name);
 
 std::cout << "Please enter your age: ";
 std::cin >> age;
 std::cin.ignore(); // Discard newline character
 
 std::cout << "Please enter your address: ";
 std::getline(std::cin, address);
 
 std::cout << "Please enter your monthly salary: ";
 std::cin >> salary;
 
 // Output registration form
 std::cout << "\n========== Registration Result ==========\n";
 std::cout << "Name: " << name << std::endl;
 std::cout << "Age: " << age << " years old" << std::endl;
 std::cout << "Address: " << address << std::endl;
 std::cout << std::fixed << std::setprecision(2);
 std::cout << "Monthly salary: " << salary << " yuan" << std::endl;
 std::cout << "==============================\n";
 
 return 0;
}

الخرج:

TEXT 📖 للعرض فقط
========== User Information Registration ==========

Please enter your name: 
Please enter your age: 
Please enter your address: 
Please enter your monthly salary: 

========== Registration Result ==========

Name: 
Age:  years old
Address: 
Monthly salary:  yuan
=============================

نتيجة التشغيل:

TEXT 📖 للعرض فقط
========== User Information Registration ==========
Please enter your name: MOTO
Please enter your age: 35
Please enter your address: Meijia Vocational College, Xiaogan, Hubei
Please enter your monthly salary: 15000

========== Registration Result ==========
Name: MOTO
Age: 35 years old
Address: Meijia Vocational College, Xiaogan, Hubei
Monthly salary: 15000.00 yuan
==============================


5. مقدمة في إدخال/إخراج الملفات (اختياري)

بخلاف القراءة من لوحة المفاتيح والكتابة على الشاشة، يمكن لـ C++ أيضًا قراءة البيانات من ملفات وكتابة البيانات إلى ملفات.

(1) 5.1 الكتابة إلى ملف

CPP
#include <iostream>
#include <fstream> // File stream header

int main() {
 std::ofstream outFile("output.txt"); // Create output file stream
 
 if (!outFile) {
 std::cout << "Cannot open file!" << std::endl;
 return 1;
 }
 
 outFile << "Hello, File!" << std::endl;
 outFile << "This is the content written to the file." << std::endl;
 
 outFile.close(); // Close the file
 std::cout << "Write successful!" << std::endl;
 
 return 0;
}

بعد التشغيل، سيُولَّد ملف output.txt في دليل البرنامج.

(2) 5.2 القراءة من ملف

TEXT 📖 للعرض فقط
#include <iostream>
#include <fstream>
#include <string>

int main() {
 std::ifstream inFile("output.txt"); // Create input file stream
 
 if (!inFile) {
 std::cout << "Cannot open file!" << std::endl;
 return 1;
 }
 
 std::string line;
 while (std::getline(inFile, line)) {
 std::cout << "Read: " << line << std::endl;
 }
 
 inFile.close();
 return 0;
}

💡 نصيحة: إدخال/إخراج الملفات موضوع كبير — هذه مجرد مقدمة مختصرة. سيكون هناك درس مخصص يغطيه بعمق لاحقًا.


❓ أسئلة شائعة

س لماذا يُخرج برنامجي أحرفًا صينية مشوهة؟
ج هذه مشكلة ترميز الأحرف الصينية في وحدة تحكم Windows. يمكنك إضافة system("chcp 65001"); في بداية برنامجك للتحويل إلى ترميز UTF-8، أو تغيير خط وحدة التحكم إلى "NSimSun". macOS/Linux عادةً لا تواجه هذه المشكلة.
س لماذا يحتاج cin وcout إلى std::؟ هل يمكن حذفه؟
ج cin/cout مُعرَّفان في فضاء الأسماء std. يمكنك استخدام using namespace std; لتجنب كتابة std::، لكن هذا غير موصى به — يمكن أن يسبب تعارضات في الأسماء. يُنصح دائمًا بكتابة std::cin، std::cout.
س كيف أمسح الشاشة؟
ج Windows: system("cls");، macOS/Linux: system("clear");. لكن هذا الأسلوب غير قابل للنقل وغير موصى به في الإنتاج — للاستخدام المؤقت فقط أثناء التعلم.
س لماذا يمكن لـ getline قراءة سلاسل نصية لكن لا تقرأ int؟
ج getline يمكنها فقط قراءة السلاسل النصية. لقراءة الأعداد الصحيحة، استخدم cin >>. إذا كنت تريد قراءة سطر كامل ثم تحليله كعدد صحيح، استخدم std::stoi(line) لتحويل سلسلة نصية إلى عدد صحيح.

▶ مثال 3: إخراج منسق (صعوبة ⭐)

CPP
#include <iostream>
#include <iomanip>

int main() {
    double price = 19.99;
    int quantity = 5;

    std::cout << "Unit price: " << std::fixed << std::setprecision(2) << price << std::endl;
    std::cout << "Quantity: " << std::setw(5) << quantity << std::endl;
    std::cout << "Total: " << price * quantity << std::endl;

    return 0;
}
▶ جرّب الكود

الخرج:

TEXT 📖 للعرض فقط
Unit price: 19.99
Quantity:     5
Total: 99.95
💡 نصيحة: std::fixed + std::setprecision(2) يحافظ على منزلتين عشريتين؛ std::setw(5) يضبط العرض.



📖 ملخص

📝 تمارين

  1. أساسي (صعوبة ⭐): اكتب برنامجًا يُخرج جدول ضرب (1-9) بالتنسيق التالي:
TEXT 📖 للعرض فقط
1 x 1 = 1
1 x 2 = 2	2 x 2 = 4
1 x 3 = 3	2 x 3 = 6	3 x 3 = 9
...

(تلميح: استخدم \t للمحاذاة وحلقات متداخلة)

  1. متوسط (صعوبة ⭐⭐): اكتب برنامجًا يتيح للمستخدم إدخال:
  2. اسم المنتج (قد يحتوي مسافات، مثل "iPhone 15 Pro")
  3. سعر الوحدة
  4. الكمية

يحسب البرنامج الإجمالي ويُخرج بتنسيق:

TEXT 📖 للعرض فقط
========== Shopping Receipt ==========
Product name: iPhone 15 Pro
Unit price: 6999.00 yuan
Quantity: 2
Total: 13998.00 yuan
==============================
  1. تحدي (صعوبة ⭐⭐⭐): اكتب برنامجًا ينفذ "إدخال دفتر عناوين":
  2. دع المستخدم يدخل معلومات 3 جهات اتصال (الاسم، الهاتف، الصلة)
  3. اكتب المعلومات إلى ملف contacts.txt
  4. ثم اقرأ من الملف واعرضه

(تلميح: استخدم ofstream للكتابة، ifstream للقراءة)


6. 🚀 الخطوة التالية

الآن بعد أن تعلمت الإدخال والإخراج، سنتعلم بعد ذلك الجمل الشرطية (if-else) (الدرس 06) — تمكين البرامج من اتخاذ القرارات وتنفيذ كود مختلف بناءً على شروط مختلفة.

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%