ไม่สามารถส่งอักขระ '#' เป็นอาร์กิวเมนต์บรรทัดคำสั่ง


36

ฉันไม่สามารถส่งผ่านสตริงที่ขึ้นต้นด้วย#อาร์กิวเมนต์บรรทัดคำสั่ง

นี่คือการทดสอบอย่างง่าย:

#include <stdio.h>

int main(int argc, char *argv[])
{
    for (int i = 1; i < argc; i++)
        printf("%s ", argv[i]);

    putchar('\n');

    return 0;
}

หากฉันป้อนอาร์กิวเมนต์ดังนี้:

2 4 # 5 6

ค่าของargcเป็นและไม่ได้3 6มันอ่าน#และหยุดอยู่แค่นั้น ผมไม่ทราบว่าทำไมและผมก็ไม่สามารถหาคำตอบในสำเนาของฉันของภาษา C ProgrammingและC รองพื้นพลัส


44
ไวยากรณ์ที่เน้นใน StackOverflow แสดงให้เห็นถึงปัญหาของคุณอย่าง :) :)
Brad Allred

คำตอบ:


47

# เริ่มแสดงความคิดเห็นใน Unix shells //ใน C

ซึ่งหมายความว่าเมื่อเชลล์ส่งอาร์กิวเมนต์ไปยัง progam จะละเว้นทุกสิ่งที่ตาม # การหนีด้วยแบ็กสแลชหรือเครื่องหมายคำพูดจะหมายถึงมันจะถูกปฏิบัติเหมือนพารามิเตอร์อื่น ๆ และโปรแกรมควรทำงานได้ตามที่คาดไว้

2 4 \# 5 6

หรือ

2 4 '#' 5 6

หรือ

2 4 "#" 5 6

โปรดทราบว่า#ตัวอักษรความคิดเห็นเป็นเพียงจุดเริ่มต้นของคำดังนั้นสิ่งนี้ควรทำงาน:

2 4#5 6

2
นี่น่าจะเป็นรายการที่ดีงามunix.stackexchange.com/a/270979
fanduin

22
@ cd-00 คุณต้องเรียนรู้ว่าเชลล์ทำงานอย่างไร สิ่งนี้ไม่เกี่ยวข้องกับรหัส C ของคุณ
chepner

3
อ่าดังนั้นคุณสามารถพิมพ์ความคิดเห็นในเซสชันเชลล์แบบโต้ตอบได้ดังนั้นเชลล์สามารถละเว้นมันได้ในทันทีหลังจากพิมพ์เสร็จแล้ว คุณสมบัติที่มีประโยชน์คืออะไร
Joker_vD

6
@Joker_vD ในขณะที่คุณคิดว่าเชลล์เป็นอินเตอร์เฟสบรรทัดคำสั่งจริงๆแล้วมันเป็นล่ามสคริปต์ ความจริงที่ว่าคุณสามารถใช้งานได้เหมือน CLI เชิงโต้ตอบเป็นโบนัสที่ดี เหตุใดการตีความจึงควรทำงานแตกต่างอย่างมากเมื่อคุณ "เรียกใช้สคริปต์" กับคำสั่งการพิมพ์ในลักษณะโต้ตอบ echo echo Hello, World | bashสิ่งที่เกี่ยวกับ มันเป็นแบบโต้ตอบหรือไม่? หรืออาจจะbash <<END?
Christopher Schultz

6
@Joker_vD: ฉันมักจะพิมพ์ความคิดเห็นในช่วงการโต้ตอบเพื่ออ้างอิงกลับในประวัติเปลือกของฉัน บางครั้งสิ่งนี้คือการบันทึกแฮชการกระทำหรือ ID อื่นที่ปล่อยออกมาเพื่อ stdout; บางครั้งมันจะต้องทราบว่าคำสั่งล้มเหลวเป็นบันทึกให้กับตัวเองในอนาคตของฉัน; บางครั้งการบันทึกข้อมูลเวลาสำหรับการเปรียบเทียบเฉพาะกิจ มันเป็นคุณสมบัติที่มีประโยชน์
wchargin

12

เมื่อส่งผ่านค่าอาร์กิวเมนต์บรรทัดคำสั่งคุณต้องทำตามคำแนะนำต่อไปนี้ อักขระต่อไปนี้มีความหมายพิเศษกับตัวเชลล์ในบางบริบทและอาจจำเป็นต้องมีการหลบหนีในอาร์กิวเมนต์:

` Backtick (U+0060 Grave Accent)
~ Tilde (U+007E)
! Exclamation mark (U+0021)
# Hash (U+0023 Number Sign)
$ Dollar sign (U+0024)
& Ampersand (U+0026)
* Asterisk (U+002A)
( Left Parenthesis (U+0028)
) Right parenthesis (U+0029)
 (⇥) Tab (U+0009)
{ Left brace (U+007B Left Curly Bracket)
[ Left square bracket (U+005B)
| Vertical bar (U+007C Vertical Line)
\ Backslash (U+005C Reverse Solidus)
; Semicolon (U+003B)
' Single quote / Apostrophe (U+0027)
" Double quote (U+0022)
↩ New line (U+000A)
< Less than (U+003C)
> Greater than (U+003E)
? Question mark (U+003F)
  Space (U+0020)1

3
แล้วพวกเขาจะหนีได้อย่างไร?
ilkkachu

3
\ - หนีโดยใช้แบ็กสแลช. EX:2 4 \{#,$,&,*} 5 6
VJAYSLN

8

เป็นเพราะคุณกำลังใช้shเปลือกที่คล้ายกัน อ้างถึง#หรือหลบหนีโดยใช้\และมันจะทำงาน

นี้เรียกว่าการแสดงความคิดเห็นshใน มันทำให้#(พื้นที่แฮช) และข้อโต้แย้งใด ๆ หลังจากที่มันจะถูกทิ้ง มันใช้ในทำนองเดียวกันกับความคิดเห็นใน C ซึ่งจะใช้ในการรหัสเอกสาร

สตริงเริ่มต้นด้วย$จะเรียกว่าตัวแปรshใน หากคุณยังไม่ได้ตั้งค่าตัวแปรมันจะขยายเป็นสตริงว่าง

ตัวอย่างเช่นทั้งหมดเหล่านี้เป็นวิธีที่ถูกต้องในการส่งผ่าน#ไปยังแอปพลิเคชันของคุณ:

2 4 '#' 5 6
2 4 "#" 5 6
2 4 \# 5 6

และนี่จะเป็นวิธีที่ถูกต้องในการส่งผ่านสตริงที่ขึ้นต้นด้วย $ :

2 4 '$var' 5 6
2 4 '$'var 5 6
2 4 \$var 5 6

โปรดทราบว่าตัวแปรภายใน"s ยังคงขยายตัว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.