Command-Line Arguments
สุขุมาภรณ์ เหมือนวงศ์ธรรม 650710096
บทนำ
โดยปกติแล้วเราสามารถส่ง Arguments ไปยัง method ผ่าน Parameter ได้ แล้วในเมธอด Main()
เราสามารถส่ง arguments ไปได้หรือไม่ ?
คำตอบคือ ' ได้ ' เราสามารถส่งพารามิเตอร์ไปยังเมธอด Main() ได้ และทำได้โดยใช้ Command-Line Arguments ที่ส่งโดยผู้ใช้หรือโปรแกรมเมอร์ไปยังเมธอด Main()
เมธอด
Main()
เป็นจุดเริ่มต้นของโปรแกรมในภาษา เมื่อตัวโปรแกรมเริ่มทำงาน เมธอดMain()
จะถูกเรียกใช้งานเป็นเมธอดแรก ทุกอย่างในโปรแกรมจะเริ่มทำงานจากที่นี่
เมธอด Main()
ในภาษา C# เมธอด Main() เป็น entry point เพียงตัวเดียวของการเริ่มทำงานโปรแกรม ในทุกโปรแกรมต้องมี เมธอด Main() เสมอ
class TestClass
{
//เมธอด Main()
static void Main(string[] args)
{
// แสดงจำนวน arguments ที่ส่งเข้ามาผ่าน command line
Console.WriteLine(args.Length);
}
}
แต่เราสามารถเขียนโค้ดในไฟล์โปรแกรมหลักได้โดยไม่ต้องสร้างเมธอด Main() ด้วยการใช้
Top-level statement ที่เขียนโค้ดโดยตรงในไฟล์โปรแกรมโดยที่ไม่ต้องห่อหุ้มโค้ดนั้นในคลาส (class) หรือเมธอด (method) ใดๆ ซึ่งโค้ดนั้นจะถูกมองว่าเป็น entry point ของโปรแกรม และ Top-level statement สามารถคืนค่าผลลัพธ์จากโปรแกรมได้ และเข้าถึง command-line arguments ได้ผ่านตัวแปร args ที่สามารถใช้ได้โดยตรงใน top-level code โดยไม่ต้องกำหนดพารามิเตอร์ใน Main()
using System.Text;
StringBuilder builder = new();
builder.AppendLine("The following arguments are passed:");
// แสดง command line arguments จากตัวแปร args
foreach (var arg in args)
{
builder.AppendLine($"Argument={arg}");
}
Console.WriteLine(builder.ToString());
// Return a success code.
return 0;
ตัวอย่างการประกาศเมธอด Main() ใน C#
// หากไม่ใช้ argument เมธอด Main() จะประกาศแบบไม่ระบุ parameter
static void Main() { }
static int Main() { }
static async Task Main() { }
static async Task<int> Main() { }
// string[] args คือพารามิเตอร์ที่เราจะส่งค่าเข้าไปผ่าน command line
static void Main() { }
static int Main(string[] args) { }
static async Task Main(string[] args) { }
static async Task<int> Main(string[] args) { }
Main() return values
เราสามารถคืนค่า int ออกมาจาก เมธอด Main() ด้วยการประกาศเมธอดแบบใดแบบหนึ่ง:
static int Main()
static int Main(string[] args)
static async Task<int> Main()
static async Task<int> Main(string[] args)
หากไม่ต้องการให้เมธอด Main() คืนค่าอะไรออกมา ให้คืนค่าเป็น void
static void Main()
static void Main(string[] args)
static async Task Main()
static async Task Main(string[] args)
Async Main() return values
เมื่อประกาศให้เมธอด Main()
คืนค่าแบบ async
(รองรับการทำงานแบบอะซิงโครนัส) ตัวคอมไพเลอร์จะสร้างโค้ดพื้นฐาน (boilerplate code) ให้สำหรับการเรียกใช้เมธอดที่ทำงานแบบอะซิงโครนัสใน Main
โดยอัตโนมัติ ซึ่งจะช่วยให้โค้ดสามารถรันได้ตามลำดับกระบวนการที่ถูกต้อง
class Program
{
//ใช้ async ในเมธอด Main โดยตรง
static async Task<int> Main(string[] args)
{
//ช้ await เพื่อรอผลลัพธ์ของการทำงาน AsyncConsoleWork โดยไม่ต้องใช้ GetAwaiter().GetResult()
return await AsyncConsoleWork();
}
private static async Task<int> AsyncConsoleWork()
{
// main body here
return 0;
}
}
แต่ถ้าไม่ได้ใช้คีย์เวิร์ด async
จะต้องเขียนโค้ดสำหรับจัดการการทำงานอะซิงโครนัสด้วยตนเอง โค้ดในตัวอย่างนี้จะทำให้แน่ใจว่าโปรแกรมจะรันจนกระทั่งการดำเนินการอะซิงโครนัสเสร็จสิ้นสมบูรณ์
class AsyncMainReturnValTest
{
//ใช้เมธอด Main โดยไม่ได้ระบุคีย์เวิร์ด async
public static int Main()
{
//.GetAwaiter().GetResult() บังคับให้รอผลลัพธ์ของงานอะซิงโครนัสแบบบล็อกการทำงาน เขียนเพิ่มเอง
return AsyncConsoleWork().GetAwaiter().GetResult();
}
//ใช้การดำเนินการอะซิงโครนัสภายในได้ โดยจะคืนค่า Task<int>
private static async Task<int> AsyncConsoleWork()
{
// Main body here
return 0;
}
}
Command-Line Arguments คืออะไร?
Command-Line Arguments คือข้อมูลที่ผู้ใช้ส่งให้กับโปรแกรมเมื่อรันจาก command line โดยจะถูกส่งเข้าไปใน parameter ของเมธอด Main(parameter)
อย่างไรก็ตาม Main()
จะไม่รับ argument จากเมธอดอื่นๆ ภายในโปรแกรม แต่จะรับค่าที่ส่งเข้ามาจาก command line เท่านั้น
เมื่อผู้ใช้ส่ง argument ให้กับโปรแกรมเมื่อรันจาก command line จะถูกส่งเข้าไปใน parameter ของเมธอด Main(string[] args)
โดยข้อมูลเหล่านี้จะถูกเก็บในตัวแปรที่ชื่อว่า args
ในรูปแบบของ array ประเภท string
ช่วยให้โปรแกรมสามารถรับข้อมูลที่แตกต่างกัน (ประเภท int, double, float, char ฯลฯ) ได้ตามที่ผู้ใช้ระบุ
เราสามารถตรวจสอบได้ว่ามี arguments อยู่ใน Main()
หรือไม่ โดยการใช้Length
ที่เป็น property ของอาร์เรย์ที่สามารถเข้าถึงได้ เพื่อบอกจำนวนสมาชิกทั้งหมดในอาร์เรย์นั้น
//จำนวนของ command-line arguments ที่อยู่ในอาร์เรย์ args ซึ่งถูกส่งเข้ามาเมื่อรันโปรแกรม
if (args.Length == 0)
{
System.Console.WriteLine("Please enter a numeric argument.");
return 1;
}
สามารถแปลง argument string เป็นประเภท int ได้โดยใช้คลาส Convert
หรือเมธอด Parse
//แปลงจาก string เป็น int
long num = Int64.Parse(args[0]);
ตัวอย่างการใช้ Command-Line Arguments ในภาษา C#
ตัวอย่างที่ 1:
//Test1.cs
using System;
namespace FirstProgram
{
class Program
{
//รับ argument
static void Main(string[] args)
{
//แสดงผล argument ที่รับเข้ามาค่าแรก
Console.WriteLine($"First Command Line Argument {args[0]}");
//แสดงผล argument ที่รับเข้ามาค่าที่สอง
Console.WriteLine($"Second Command Line Argument {args[1]}");
//แสดงผล argument ที่รับเข้ามาค่าที่สาม
Console.WriteLine($"Third Command Line Argument {args[2]}");
}
}
}
วิธีการส่งค่า argument ผ่านทาง command line
เปิด Command Prompt หรือ Terminal ในโฟลเดอร์ที่มีไฟล์
Test1.cs
compile โปรแกรมด้วยคำสั่ง
dotnet build
รันโปรแกรมด้วยคำสั่ง
dotnet run
พร้อมระบุ argument ที่จะส่งไป
Iutput:
//ไม่ใส่ -- เมื่อส่ง argument ไม่มีเครื่องหมาย - หรือ -- นำหน้า
dotnet run value1 value2 value3
Output:
First Command Line Argument value1
Second Command Line Argument value2
Third Command Line Argument value3
ตัวอย่างที่ 2:C#
//Program.cs
public class Functions
{
public static long Factorial(int n)
{
// Test for invalid input.
if ((n < 0) || (n > 20))
{
return -1;
}
// Calculate the factorial iteratively rather than recursively.
long tempResult = 1;
for (int i = 1; i <= n; i++)
{
tempResult *= i;
}
return tempResult;
}
}
class MainClass
{
static int Main(string[] args)
{
// ทดสอบว่ามีการระบุ argument อินพุตหรือไม่
if (args.Length == 0)
{
Console.WriteLine("Please enter a numeric argument.");
Console.WriteLine("Usage: Factorial <num>");
return 1;
}
// Try to convert the input arguments to numbers. This will throw
// an exception if the argument is not a number.
// num = int.Parse(args[0]);
int num;
bool test = int.TryParse(args[0], out num);
if (!test)
{
Console.WriteLine("Please enter a numeric argument.");
Console.WriteLine("Usage: Factorial <num>");
return 1;
}
// คำนวณ factorial.
long result = Functions.Factorial(num);
// แสดงผลลัพธ์
if (result == -1)
Console.WriteLine("Input must be >= 0 and <= 20.");
else
Console.WriteLine($"The Factorial of {num} is {result}.");
return 0;
}
}
Iutput:
//-- ใช้แยก argument ที่ถูกส่งไปให้ CLI (เครื่องมือที่ใช้จัดการโครงสร้าง .NET) กับ argument ที่ถูกส่งไปให้โปรแกรมที่คุณรัน
dotnet run -- 3
Output:
The factorial of 3 is 6
เปรียบเทียบ Command-Line Arguments กับภาษา Java, C, Python
Java
ใน Java เมื่อโปรแกรมถูกเรียกใช้ JVM (Java Virtual Machine) จะเริ่มรันจากเมธอด main()
เป็นอันดับแรก โดยเราสามารถส่งค่า argument ไปที่เมธอด main()
ด้วย command line ผ่านทาง parameter ของเมธอด main(String[] args)
เราสามารถส่งข้อมูลประเภท int, double, float, char ฯลฯ ได้โดยข้อมูลเหล่านี้จะถูกเก็บในตัวแปรที่ชื่อว่า args
ในรูปแบบของ array ประเภท String
เหมือนกับภาษา C#
เมื่อส่ง argument ไปยัง JVM แล้ว JVM จะห่อ argument เหล่านี้และส่งไปยัง args[] สามารถตรวจสอบจำนวนของ argument ที่ถูกส่งเข้ามาผ่าน command line ในโดยใช้เมธอด args.length JVM จะจัดเก็บ argument แรกไว้ที่ args[0] argument ที่สองไว้ที่ args[1] argument ที่สามไว้ที่ args[2] อย่างนี้ไปเรื่อยๆ
พารามิเตอร์ในเมธอด
Main:
Java ฟังก์ชันmain
ใน Java ต้องมีString[] args
เป็นพารามิเตอร์เสมอ และ return type เป็นvoid
เท่านั้น C# ฟังก์ชันMain
ใน C# มีความยืดหยุ่นมากกว่า สามารถ return ค่าเป็นvoid
,int
,Task
, หรือTask<int>
ได้ และรองรับการใช้async
สำหรับการทำงานแบบอะซิงโครนัส
C
ฟังก์ชัน main()
ในภาษา C มักจะเขียนโดยไม่มี Argument และมีการส่งคืนค่าเป็น 0
หรือไม่มีการส่งคืนค่า โดยปกติภายในฟังก์ชัน main() มีคำสั่ง scanf()
เพื่อให้ผู้ใช้ป้อนค่าเข้าไป แต่แทนที่จะเขียนโค้ดค่าต่างๆ เหล่านั้นไว้ภายในโค้ด เราสามารถส่งค่า หรือ argument จาก command line ไปยังฟังก์ชัน main()
ได้ เมื่อโปรแกรมทำงาน ค่าเหล่านี้จะถูกเรียกว่า Command-Line Arguments โปรแกรมสามารถรับข้อมูลนี้ผ่านฟังก์ชัน main()
โดยผ่านพารามิเตอร์สองตัว คือ
argc
(argument count): บอกจำนวนของ arguments ที่ส่งเข้ามา ควรเป็นค่าบวกเสมอ
argv[]
(argument vector): เป็น array ของ strings เป็นตัวชี้ที่ไปยัง arguments จริง ๆทั้งหมด โดย argv[0]
มักเป็นชื่อของโปรแกรม
การประกาศ: C ต้องการ
argc
และargv
ในmain
ในขณะที่ C# ใช้string[] args
การเข้าถึง: C ใช้
char *argv[]
และ C# ใช้string[] args
index ของ argument แรก: C
argv[0]
คือ ชื่อโปรแกรม แต่ C#args[0]
คือ argument แรก
Python
Python มีวิธีหลากหลายในการใช้ Command-Line Arguments เช่น sys.argv
โมดูล sys ให้ฟังก์ชันและตัวแปรที่ใช้เพื่อจัดการส่วนต่างๆ ของ Python runtime environment โมดูลนี้ให้การเข้าถึงตัวแปรบางตัวที่ใช้หรือบำรุงรักษาโดย Interpreter และฟังก์ชันที่โต้ตอบกับ Interpreter เช่นตัวแปร sys.argv
ซึ่งเป็นโครงสร้างของ list แบบง่าย วัตถุประสงค์หลัก คือเป็น lists ของ Command-Line Arguments
sys.argv[0]
คือชื่อของสคริปต์ Python
len(sys.argv)
ระบุจำนวน arguments ที่โปรแกรมรับเข้ามาจะรวมถึงชื่อไฟล์สคริปต์ด้วย
การนำเข้า: Python ต้องนำเข้า
sys
โมดูล ในขณะที่ C# ใช้พารามิเตอร์ในMain
การประกาศ: Python ไม่มีการประกาศ
main
เฉพาะ ขณะที่ C# ต้องมีเมธอดMain
การจัดการ: Python ใช้
sys.argv
ซึ่งเป็นลิสต์เพื่อเก็บ arguments ขณะที่ C# ใช้string[] args
index ของ argument แรก: Python
sys.argv[0]
คือชื่อของสคริปต์ Python แต่ C#args[0]
คือ argument แรก
Code ของแต่ละภาษา
//Test.cs
using System;
class Test {
public static void Main(string[] args) {
// แสดงจำนวน arguments
Console.WriteLine("Total arguments: " + args.Length);
// แสดงแต่ละ argument
for (int i = 0; i < args.Length; i++) {
Console.WriteLine("Argument " + i + ": " + args[i]);
}
}
}
วิธีการส่งค่า argument ผ่านทาง command line ของแต่ละภาษา
เปิด Command Prompt หรือ Terminal ในโฟลเดอร์ที่มีไฟล์
Test.cs
compile โปรแกรมด้วยคำสั่ง
dotnet build
รันโปรแกรมด้วยคำสั่ง
dotnet run
พร้อมระบุ argument ที่จะส่งไป
Input :
dotnet run a b c 1 2 3 4.0 def
Output
Total arguments: 8
Argument 0: a
Argument 1: b
Argument 2: c
Argument 3: 1
Argument 4: 2
Argument 5: 3
Argument 6: 4.0
Argument 7: def
ตารางเปรียบเทียบการใช้งาน command-line arguments ในภาษา C#, Java, C, และ Python
พารามิเตอร์ในเมธอด Main
static void Main(string[] args)
public static void main(String[] args)
int main(int argc, char *argv[])
import sys
ชนิดของ arguments
string[] args
(อาร์เรย์ของ string)
String[] args
(อาร์เรย์ของ string)
char *argv[]
(อาร์เรย์ของ string) + int argc
(จำนวน arguments)
sys.argv
(ลิสต์ของ string)
การเข้าถึง arguments
args[i]
args[i]
argv[i]
sys.argv[i]
จำนวนของ arguments
args.Length
args.length
argc
len(sys.argv)
index ของ argument แรก
args[0]
(argument แรก ไม่มีชื่อโปรแกรม)
args[0]
(argument แรก ไม่มีชื่อโปรแกรม)
argv[1]
(argument แรก, argv[0]
คือชื่อโปรแกรม)
sys.argv[1]
(argument แรก, sys.argv[0]
คือชื่อสคริปต์)
จำนวนของ arguments ในการรัน command line
dotnet run -- arg1 arg2 ...
java Test arg1 arg2 ...
Test.exe arg1 arg2 ...
python Test.py arg1 arg2 ...
Link Video
Slides
References
เนื้อหาและตัวอย่างของภาษา C#
ตัวอย่างที่ใช้ในการเปรียบเทียบของแต่ละภาษา:
น.ท.ไพศาล โมลิสกุลมงคล. (ตุลาคม 2545). Microsoft Visual C#.NET. กรุงเทพฯ: หจก.ไทยเจริญการพิมพ์.
เนื้อหาและตัวอย่างที่ 2 ใน C#:
เนื้อหาเพิ่มเติม:
ตัวอย่างที่ 1 ใน C#:
เนื้อหาการเปรียบเทียบกับภาษา Java, C, Python
Java:
C:
Python:
Last updated