كيفية القراءة من الإدخال القياسي في Go: من المبتدئ إلى المحترف
\n\nهل تساءلت يومًا كيف تجعل برنامج Go الخاص بك «يستمع» إلى المستخدم؟ كيف تكتب أداة تقبل الأوامر من وحدة التحكم، أو أداة CLI تفاعلية؟ إذا كان الأمر كذلك، فأنت في المكان الصحيح. اليوم سنشرح القراءة من الإدخال القياسي (stdin) في Go — بأكبر قدر ممكن من التفصيل.
\n\nهذا الموضوع هو من أكثر المواضيع شيوعًا على Stack Overflow. السؤال «How can I read from standard input in the console?» حصد آلاف المشاهدات. وليس من دون سبب: الإدخال القياسي هو الأساس الذي لا يمكن لأي مشروع جاد في Go الاستغناء عنه. نحن نُكيّف هذا السؤال للجمهور الناطق بالعربية ونحوله إلى برنامج تعليمي كامل.
\n\nفي هذه المقالة، ستتعلم:
\n- \n
- ما هو
os.Stdinوكيفية العمل معه \n - كيفية استخدام
bufio.Scannerللقراءة سطرًا سطرًا \n - لماذا
fmt.Scanهو سلاح ذو حدين \n - كيفية قراءة ملفات كاملة من stdin \n
- أسرار معالجة الأخطاء والأداء \n
هيا بنا!
\n\nما هو stdin ولماذا هو مهم في Go؟
\n\nالإدخال القياسي (stdin) هو تيار بيانات يستقبله برنامجك من وحدة التحكم أو من عملية أخرى. في Go، يتم تمثيله بواسطة المتغير os.Stdin من النوع *os.File. إنها البوابة التي تمر من خلالها البيانات إلى برنامجك.
لماذا هذا مهم؟ تخيل:
\n- \n
- أنت تكتب أداة CLI تعالج إدخال المستخدم \n
- أنشئ محلل سجلات يقرأ البيانات عبر أنبوب (
cat log.txt | myapp) \n - تحتاج إلى تنفيذ إدخال تفاعلي مع تلميحات \n
Go، باعتبارها لغة للبرمجة النظامية، توفر أدوات أنيقة للعمل مع stdin. دعنا نستعرضها بالترتيب.
\n\nالطريقة 1: bufio.Scanner — ملك القراءة سطرًا سطرًا
\n\nالطريقة الأكثر شيوعًا والموصى بها للقراءة من stdin في Go هي bufio.Scanner. إنها بسيطة وفعالة وتحل 90% من المهام.
إليك مثالًا كلاسيكيًا:
\n\npackage main\n\nimport (\n "bufio"\n "fmt"\n "os"\n)\n\nfunc main() {\n scanner := bufio.NewScanner(os.Stdin)\n fmt.Println("أدخل النص (Ctrl+D للإنهاء):")\n \n for scanner.Scan() {\n line := scanner.Text()\n fmt.Println("لقد أدخلت:", line)\n }\n \n if err := scanner.Err(); err != nil {\n fmt.Fprintln(os.Stderr, "خطأ في القراءة:", err)\n }\n}\n\nكيف يعمل هذا؟
\n- \n
bufio.NewScanner(os.Stdin)— ينشئ ماسحًا ضوئيًا يقرأ من الإدخال القياسي \n scanner.Scan()— يُرجعtrueطالما توجد بيانات (افتراضيًا حتى حرف السطر الجديد) \n scanner.Text()— يُرجع السطر الحالي بدون حرف\\n\n - تتوقف الحلقة عند
EOF(Ctrl+D في Linux/Mac، Ctrl+Z في Windows) \n
هذا الكود هو الأساس لأي إدخال من وحدة التحكم في Go. يعمل بشكل ممتاز مع الأنابيب والإدخال التفاعلي.
\n\nتخصيص الماسح الضوئي
\n\nافتراضيًا، يقسم Scanner الإدخال حسب الأسطر. لكن يمكنك تغيير ذلك:
// القراءة حسب الكلمات\nscanner.Split(bufio.ScanWords)\n\n// القراءة حسب البايتات\nscanner.Split(bufio.ScanBytes)\n\n// القراءة حسب الأحرف (الرونات)\nscanner.Split(bufio.ScanRunes)\n\nيمكنك أيضًا تعيين مقسم خاص بك — على سبيل المثال، لملفات CSV أو فواصل مخصصة. لكن هذا موضوع لمقال منفصل.
\n\nالطريقة 2: fmt.Scan — سريع وقذر
\n\nإذا كنت بحاجة إلى إدخال قيمة واحدة — رقم، سلسلة نصية، أو عدة متغيرات — فإن fmt.Scan سيساعدك. إنها مثل scanf في لغة C، ولكن