อะไรคือความแตกต่างระหว่าง\n
(ขึ้นบรรทัดใหม่) และ\r
(การคืนสินค้า)?
โดยเฉพาะมีความแตกต่างในทางปฏิบัติระหว่าง\n
และ\r
? มีสถานที่ที่ควรใช้อย่างใดอย่างหนึ่งแทนสถานที่อื่น ๆ ?
อะไรคือความแตกต่างระหว่าง\n
(ขึ้นบรรทัดใหม่) และ\r
(การคืนสินค้า)?
โดยเฉพาะมีความแตกต่างในทางปฏิบัติระหว่าง\n
และ\r
? มีสถานที่ที่ควรใช้อย่างใดอย่างหนึ่งแทนสถานที่อื่น ๆ ?
คำตอบ:
ในแง่ของรหัส ASCII มันเป็น 3 - เนื่องจากมันคือ 10 และ 13 ตามลำดับ ;-)
แต่จริงจังมีหลาย:
\n
คือรหัสสำหรับ end-of-line \r
ไม่มีความหมายอะไรเป็นพิเศษ\n
เป็นลำดับการหลบหนีมาตรฐานสำหรับจุดสิ้นสุดของบรรทัด (แปลเป็น / จากลำดับเฉพาะ OS ตามความจำเป็น)\r
เป็นรหัสสำหรับ end-of-line แทน\r\n
ตามลำดับนี้\r\n
เป็นบรรทัดการเลิกจ้างมาตรฐานสำหรับรูปแบบข้อความบนอินเทอร์เน็ต\r
สั่งให้แคร่เลื่อนกลับไปทางซ้ายจนกว่าจะถึงจุดหยุดสุดซ้าย (การทำงานที่ช้า) \n
สั่งให้ลูกกลิ้งหมุนหนึ่งบรรทัด\r
ก่อน \n
เพื่อให้ลูกกลิ้งสามารถย้ายในขณะที่สายการบินยังคงเป็นไป leftwards -!) วิกิพีเดียมีคำอธิบายรายละเอียดเพิ่มเติม\r
และ\n
ทำหน้าที่ในทำนองเดียวกัน (ยกเว้นทั้งในแง่ของเคอร์เซอร์ที่มีคือไม่มีสายการบินหรือลูกกลิ้ง ;-)ในทางปฏิบัติในบริบทที่ทันสมัยของการเขียนไปยังไฟล์ข้อความคุณควรใช้เสมอ\n
(รันไทม์พื้นฐานจะแปลว่าถ้าคุณอยู่ในระบบปฏิบัติการแปลก ๆ เช่น Windows ;-) เหตุผลเดียวที่ใช้\r
คือถ้าคุณเขียนไปที่เทอร์มินัลตัวละคร (หรือมีแนวโน้มว่า "คอนโซลหน้าต่าง" เลียนแบบ) และต้องการให้บรรทัดถัดไปที่คุณเขียนเพื่อเขียนทับอันสุดท้ายที่คุณเพิ่งเขียน (บางครั้งใช้สำหรับ "เอฟเฟ็กต์ของแถบความคืบหน้าเช่น) - สิ่งนี้ล้าสมัยไปแล้วในโลกของ GUI แม้ว่า ;-)
\0
) หลังจาก\n
เพิ่ม เวลา. สิ่งนี้ถูกจัดการโดยระบบปฏิบัติการอย่างโปร่งใสดังนั้นคุณจะไม่พบร่องรอยใด ๆ ในรหัสดั้งเดิม
\r
(ฉันใช้ Linux) เมื่อฉันเริ่มการแยกวิเคราะห์สิ่งที่ดูเหมือนว่าจะเป็นไฟล์ที่ถูกต้องตัวแยกวิเคราะห์ของฉันล้มเหลวเพราะไฟล์ที่ฉันแยกได้ถูกสร้างขึ้นใน Windows : D ปัญหาหลักในสิ่งที่มีอยู่ว่าไม่\n
หรือ\r
จะมองเห็นได้ในแง่ที่ว่าเช่นa
, .
, (
ฯลฯ ตัวอักษร
ในอดีต\n
เคยถูกใช้เพื่อเคลื่อนย้ายแคร่ลงในขณะที่\r
ใช้เพื่อย้ายแคร่กลับไปทางด้านซ้ายของหน้า
printf("abcdefghijlm\rNOP\n");
คอมไพล์ด้วย gcc-8 บน OpenSuSe และรันบนผลลัพธ์เทอร์มินัลในเอาต์พุตNOPdefghijlm
นี้ \ r (carriage return) ในสตริงส่งผลให้เคอร์เซอร์เลื่อนไปที่จุดเริ่มต้นของบรรทัด (carriage) และตัวอักษรที่ตามหลัง \ r (เช่น "NOP") เขียนทับสิ่งที่เคยมี (เช่น "abc")! คุณสามารถบรรลุ "ขบวนการขนส่ง" ที่คล้ายกันด้วย backspace (\ b) ตามprintf("abcdefghijlm\b\bNOP\n");
ที่ผลิตabcdefghijNOP
อักขระสองตัวที่แตกต่างกัน
\n
ใช้เป็นจุดสิ้นสุดของบรรทัดในไฟล์ข้อความ Unix
\r
ใช้เป็นจุดสิ้นสุดของบรรทัดในไฟล์ข้อความ Mac
\r\n
(เช่นทั้งสองอย่าง) ถูกใช้เพื่อยกเลิกบรรทัดในไฟล์ข้อความ Windows และ DOS
\r
ยังไม่ได้รับการสิ้นสุดบรรทัดบน Mac มาเป็นเวลานาน ด้วยการเปิดตัว Mac OS X ในปี 2001 (ซึ่งใช้ Unix) \n
จะถูกนำมาใช้ในขณะนี้
\r
เช่น MS Office 2011 Excel: การบันทึก CSV (ด้วยการตั้งค่าเริ่มต้นทั้งหมด) - จะบันทึกไฟล์ที่เข้ารหัส ISO-8859-1 ด้วยการ\r
สิ้นสุดบรรทัด
เนื่องจากไม่มีใครพูดถึงมันโดยเฉพาะ (พวกมันยังเด็กเกินกว่าจะรู้ / จำได้?) - ฉันสงสัยว่ามีการใช้\r\n
เครื่องกำเนิดไฟฟ้าสำหรับเครื่องพิมพ์ดีดและอุปกรณ์ที่คล้ายกัน
เมื่อคุณต้องการขึ้นบรรทัดใหม่ในขณะที่ใช้เครื่องพิมพ์ดีดที่มีความสามารถหลายบรรทัดมีการกระทำทางกายภาพสองอย่างที่ต้องปฏิบัติ: เลื่อนแคร่กลับไปที่จุดเริ่มต้น (ซ้ายในสหรัฐอเมริกา) ของหน้ากระดาษและป้อนกระดาษหนึ่งรอย .
ย้อนกลับไปในยุคสมัยของเครื่องพิมพ์บรรทัดวิธีเดียวที่จะทำข้อความที่เป็นตัวหนาตัวอย่างเช่นทำ carriage return โดยไม่ต้องขึ้นบรรทัดใหม่และพิมพ์อักขระเดียวกันเหนือตัวเก่าทำให้เพิ่มหมึกมากขึ้นทำให้เข้มขึ้น (ตัวหนา) . เมื่อฟังก์ชัน "บรรทัดใหม่" เชิงกลล้มเหลวในเครื่องพิมพ์ดีดนี่เป็นผลลัพธ์ที่น่ารำคาญ: คุณสามารถพิมพ์ทับบรรทัดข้อความก่อนหน้าหากคุณไม่สนใจ
อักขระสองตัวที่แตกต่างกันสำหรับระบบปฏิบัติการที่แตกต่างกัน นอกจากนี้มีบทบาทในการส่งข้อมูลมากกว่าTCP/IP
\r\n
ซึ่งจะต้องมีการใช้งานของ
\n
ยูนิกซ์
\r
Mac
\r\n
Windows และ DOS
ทำให้สำเร็จ,
ในสคริปต์เชลล์ (ทุบตี) คุณสามารถใช้\r
เพื่อส่งเคอร์เซอร์หน้าบรรทัดและแน่นอน\n
จะวางเคอร์เซอร์บนบรรทัดใหม่
ตัวอย่างเช่นลอง:
echo -en "AA--AA" ; echo -en "BB" ; echo -en "\rBB"
AA--AA
AA--AABB
BB--AABB
แต่อย่าลืมใช้-en
เป็นพารามิเตอร์
ใน windows \ n จะย้ายไปที่จุดเริ่มต้นของบรรทัดถัดไป \ r ย้ายไปยังจุดเริ่มต้นของบรรทัดปัจจุบันโดยไม่ย้ายไปยังบรรทัดถัดไป ฉันใช้ \ r ในแอปคอนโซลของฉันซึ่งฉันกำลังทดสอบโค้ดบางตัวและฉันไม่ต้องการเห็นข้อความที่เลื่อนขึ้นหน้าจอดังนั้นแทนที่จะใช้ \ n หลังจากพิมพ์ข้อความบางส่วนอัตราเฟรม ( FPS) ฉันจะพิมพ์ ("% - 10d \ r", fps); นี่จะกลับเคอร์เซอร์ไปที่จุดเริ่มต้นของบรรทัดโดยไม่ต้องเลื่อนลงไปที่บรรทัดถัดไปและอนุญาตให้ฉันมีข้อมูลอื่น ๆ บนหน้าจอที่ไม่ได้เลื่อนออกในขณะที่ framerate ปรับปรุงอยู่เสมอในบรรทัดเดียวกัน (% -10 ทำให้ มั่นใจว่าเอาต์พุตมีอย่างน้อย 10 ตัวอักษรโดยมีการปรับชิดซ้ายเพื่อให้มีการเว้นวรรคและเขียนทับค่าเก่าสำหรับบรรทัดนั้น) มันค่อนข้างมีประโยชน์สำหรับเรื่องแบบนี้
ประวัติเล็กน้อย
/ r ย่อมาจาก "return" หรือ "carriage return" ซึ่งเป็นหนี้จากประวัติของเครื่องพิมพ์ดีด การขึ้นบรรทัดใหม่ได้เลื่อนแคร่ของคุณไปทางด้านขวาเพื่อให้คุณพิมพ์ที่จุดเริ่มต้นของบรรทัด
/ n ย่อมาจาก "new line" อีกครั้งจากเครื่องพิมพ์ดีดวันที่คุณย้ายไปยังบรรทัดใหม่ ไม่จำเป็นต้องเริ่มต้นด้วยเหตุนี้เองซึ่งเป็นเหตุผลว่าทำไมระบบปฏิบัติการ OS บางเครื่องจำเป็นต้องใช้ทั้ง a / r return ตามด้วย a / n newline เนื่องจากเป็นคำสั่งที่เครื่องพิมพ์ดีดทำอยู่มันอธิบายคอมพิวเตอร์ 8 บิตเก่าที่ใช้ ที่จะมี "Return" มากกว่า "Enter" จาก "carriage return" ซึ่งเป็นที่คุ้นเคย
เพื่อเพิ่มความสับสนฉันได้ทำงานกับเครื่องมือแก้ไขข้อความอย่างง่ายโดยใช้องค์ประกอบ TextArea ในหน้า HTML ในเบราว์เซอร์ ในความคาดหมายของความเข้ากันได้ที่เกิดขึ้นกับ CR / LF ฉันเขียนโค้ดเพื่อตรวจสอบแพลตฟอร์มและใช้ข้อตกลงการขึ้นบรรทัดใหม่ที่เกี่ยวข้องกับแพลตฟอร์ม
อย่างไรก็ตามฉันค้นพบสิ่งที่น่าสนใจเมื่อตรวจสอบอักขระจริงที่มีอยู่ใน TextArea ผ่านฟังก์ชัน JavaScript ขนาดเล็กที่สร้างข้อมูลฐานสิบหกที่สอดคล้องกับอักขระ
สำหรับการทดสอบฉันพิมพ์ข้อความต่อไปนี้:
สวัสดีทุกคนในโลก [Enter]
ลาก่อน Cruel World [Enter]
เมื่อฉันตรวจสอบข้อมูลข้อความลำดับไบต์ที่ฉันได้รับคือ:
48 65 6c 6c 6f 2c 20 57 6f 72 6c 64 0a 47 6f 6f 64 62 79 65 2c 20 43 72 75 65 6c 20 57 6f 72 6c 64 0a
ตอนนี้คนส่วนใหญ่มองที่นี่และเห็น 0a แต่ไม่มี 0d ไบต์จะคิดว่าผลลัพธ์นี้ได้มาจากแพลตฟอร์ม Unix / Linux แต่นี่คือสิ่งที่ถู: ลำดับนี้ที่ฉันได้รับใน Google Chrome บน Windows 7 64-bit
ดังนั้นหากคุณกำลังใช้องค์ประกอบ TextArea และตรวจสอบข้อความให้ตรวจสอบผลลัพธ์ที่ฉันได้ทำไปแล้วเพื่อให้แน่ใจว่าไบต์ตัวอักษรที่แท้จริงจะถูกส่งกลับจาก TextArea ของคุณ ฉันยังไม่ได้ดูว่าสิ่งนี้จะแตกต่างกับแพลตฟอร์มอื่น ๆ หรือเบราว์เซอร์อื่น ๆ แต่ควรคำนึงถึงว่าคุณกำลังทำการประมวลผลข้อความผ่าน JavaScript หรือไม่และคุณต้องทำให้แพลตฟอร์มการประมวลผลข้อความเป็นอิสระ
อนุสัญญาที่กล่าวถึงในโพสต์ด้านบนนั้นใช้กับเอาท์พุทของคอนโซลแต่องค์ประกอบ HTML ก็ปรากฏขึ้นซึ่งเป็นไปตามอนุสัญญา UNIX / Linux ถ้าไม่มีใครค้นพบเป็นอย่างอื่นบนแพลตฟอร์ม / เบราว์เซอร์อื่น
#include <stdio.h>
void main()
{
int countch=0;
int countwd=1;
printf("Enter your sentence in lowercase: ");
char ch='a';
while(ch!='\r')
{
ch=getche();
if(ch==' ')
countwd++;
else
countch++;
}
printf("\n Words = ",countwd);
printf("Characters = ",countch-1);
getch();
}
ลองทำตัวอย่างนี้ลองวาง \ n แทน \ r มันจะไม่ทำงานและลองเดาว่าทำไม
Return
Enter
แม้แป้นพิมพ์ไร้สายของฉันที่ทันสมัยยังคงแสดงให้เห็นถึงลงและลูกศรย้อนกลับเก่าReturn
ที่สำคัญ (ซึ่งมีบรรดาศักดิ์เป็นตอนนี้ "Enter" เพื่อให้สอดคล้องกับแป้นพิมพ์ตัวเลขของEnter
สำคัญซึ่งไม่ได้แสดงลูกศร)
อะไรคือความแตกต่างระหว่าง \ n (ขึ้นบรรทัดใหม่) และ \ r (การขึ้นบรรทัดใหม่)
โดยเฉพาะมีความแตกต่างในทางปฏิบัติระหว่าง
\n
และ\r
? มีสถานที่ที่ควรใช้อย่างใดอย่างหนึ่งแทนสถานที่อื่น ๆ ?
ฉันต้องการทำการทดสอบสั้น ๆ กับลำดับการหลบหนีที่เกี่ยวข้องของ\n
สำหรับการขึ้นบรรทัดใหม่และ\r
สำหรับการขึ้นบรรทัดใหม่เพื่อแสดงให้เห็นถึงความแตกต่างที่ชัดเจนระหว่างพวกเขา
ฉันรู้ว่าคำถามนี้ถูกถามเป็นภาษาอิสระ อย่างไรก็ตามเราต้องการภาษาอย่างน้อยเพื่อให้การทดสอบสำเร็จ ในกรณีของฉันฉันได้เลือก C ++ แต่โดยทั่วไปแล้วการทดสอบจะใช้งานได้กับภาษาการเขียนโปรแกรมใด ๆ
โปรแกรมเพียงแค่วนซ้ำเพื่อพิมพ์ประโยคลงในคอนโซลทำโดยการวนซ้ำแบบวนซ้ำ
โปรแกรม Newline:
#include <iostream>
int main(void)
{
for(int i = 0; i < 7; i++)
{
std::cout << i + 1 <<".Walkthrough of the for-loop \n"; // Notice `\n` at the end.
}
return 0;
}
เอาท์พุท:
1.Walkthrough of the for-loop
2.Walkthrough of the for-loop
3.Walkthrough of the for-loop
4.Walkthrough of the for-loop
5.Walkthrough of the for-loop
6.Walkthrough of the for-loop
7.Walkthrough of the for-loop
โปรดสังเกตว่าผลลัพธ์นี้จะไม่ถูกจัดเตรียมไว้ในระบบใด ๆคุณกำลังเรียกใช้งานรหัส C ++ นี้ แต่มันจะใช้ได้กับระบบที่ทันสมัยที่สุด อ่านด้านล่างสำหรับรายละเอียดเพิ่มเติม
ตอนนี้โปรแกรมเดียวกัน แต่มีความแตกต่างที่\n
ถูกแทนที่ด้วย\r
ในตอนท้ายของลำดับการพิมพ์
โปรแกรมรับคืน:
#include <iostream>
int main(void)
{
for(int i = 0; i < 7; i++)
{
std::cout << i + 1 <<".Walkthrough of the for-loop \r"; // Notice `\r` at the end.
}
return 0;
}
เอาท์พุท:
7.Walkthrough of the for-loop
สังเกตเห็นความแตกต่างอยู่ที่ไหน ความแตกต่างนั้นง่ายเหมือนกันเมื่อคุณใช้ลำดับการหลบหนีของ Carriage Return \r
ที่ส่วนท้ายของลำดับการพิมพ์แต่ละครั้งการทำซ้ำครั้งถัดไปของลำดับนี้ไม่ได้รับในบรรทัดข้อความต่อไปนี้ - ในตอนท้ายของแต่ละลำดับการพิมพ์เคอร์เซอร์ไม่ได้ ข้ามไปที่ * จุดเริ่มต้นของบรรทัดถัดไป
แต่เคอร์เซอร์จะกระโดดกลับไปที่จุดเริ่มต้นของบรรทัดซึ่งเขาอยู่ที่จุดสิ้นสุดก่อนที่จะใช้\r
อักขระ - ผลลัพธ์คือแต่ละการวนซ้ำของลำดับการพิมพ์ต่อไปนี้เป็นการแทนที่ลำดับก่อนหน้า
* หมายเหตุ: A \n
ไม่จำเป็นต้องข้ามไปยังจุดเริ่มต้นของบรรทัดข้อความต่อไปนี้ ในบางทั่วไปผู้อาวุโสมากขึ้นระบบปฏิบัติการผลลัพธ์ของ\n
อักขระขึ้นบรรทัดใหม่สามารถข้ามไปที่ใดก็ได้ในบรรทัดต่อไปนี้ไม่ใช่เฉพาะกับจุดเริ่มต้น นั่นคือเหตุผลที่พวกเขาจำเป็นต้องใช้\r \n
เพื่อเริ่มต้นบรรทัดข้อความถัดไป
การทดลองนี้แสดงให้เราเห็นถึงความแตกต่างระหว่างการขึ้นบรรทัดใหม่และการปัดแคร่ในบริบทของผลลัพธ์ของการวนซ้ำของลำดับการพิมพ์
เมื่อพูดคุยเกี่ยวกับอินพุตในโปรแกรมเทอร์มินัล / คอนโซลบางอย่างอาจแปลงการขึ้นบรรทัดใหม่เป็นบรรทัดใหม่เพื่อความสะดวกในการพกพาความเข้ากันได้และความสมบูรณ์
แต่ถ้าคุณมีทางเลือกให้เลือกแบบอื่นหรือต้องการหรือต้องการใช้อย่างชัดเจนคุณควรใช้งานกับสิ่งที่เหมาะสมกับวัตถุประสงค์และแยกความแตกต่างอย่างเคร่งครัด