มีวิธีระบุจำนวนอักขระของสตริงที่จะพิมพ์โดยใช้ printf () หรือไม่?


127

มีวิธีระบุจำนวนอักขระของสตริงที่จะพิมพ์ออกมา (คล้ายกับตำแหน่งทศนิยมในints) หรือไม่?

printf ("Here are the first 8 chars: %s\n", "A string that is more than 8 chars");

ต้องการให้พิมพ์: Here are the first 8 chars: A string

คำตอบ:


227

วิธีพื้นฐานคือ:

printf ("Here are the first 8 chars: %.8s\n", "A string that is more than 8 chars");

อีกวิธีหนึ่งที่มักมีประโยชน์กว่าคือ:

printf ("Here are the first %d chars: %.*s\n", 8, 8, "A string that is more than 8 chars");

ที่นี่คุณระบุความยาวเป็นอาร์กิวเมนต์ int ให้กับ printf () ซึ่งถือว่า '*' ในรูปแบบเป็นคำขอเพื่อรับความยาวจากอาร์กิวเมนต์

คุณยังสามารถใช้สัญกรณ์:

printf ("Here are the first 8 chars: %*.*s\n",
        8, 8, "A string that is more than 8 chars");

นอกจากนี้ยังคล้ายคลึงกับสัญกรณ์ "% 8.8s" แต่อีกครั้งช่วยให้คุณสามารถระบุความยาวต่ำสุดและสูงสุดที่รันไทม์ได้ - สมจริงมากขึ้นในสถานการณ์เช่น:

printf("Data: %*.*s Other info: %d\n", minlen, maxlen, string, info);

ข้อกำหนด POSIX สำหรับprintf()กำหนดกลไกเหล่านี้


2
ในตัวอย่างสุดท้าย: จะเกิดอะไรขึ้นถ้าสตริงที่คัดลอกสั้นกว่า minlen?
truthseeker

4
เอาต์พุตจะเป็นเบาะว่าง (ทางด้านซ้ายเว้นแต่คุณจะเพิ่ม a -) เพื่อให้ได้เต็มความยาวที่ระบุ
Jonathan Leffler

13
printf ("Here are the first 8 chars: %.8s\n", "A string that is more than 8 chars");

% 8s จะระบุความกว้างขั้นต่ำ 8 อักขระ คุณต้องการตัดทอนที่ 8 ดังนั้นให้ใช้% .8s

หากคุณต้องการพิมพ์ 8 ตัวอักษรเสมอคุณสามารถใช้% 8.8s


13

นอกเหนือจากการระบุจำนวนอักขระคงที่แล้วคุณยังสามารถใช้*ซึ่งหมายความว่า printf ใช้จำนวนอักขระจากอาร์กิวเมนต์:

#include <stdio.h>

int main(int argc, char *argv[])
{
        const char hello[] = "Hello world";
        printf("message: '%.3s'\n", hello);
        printf("message: '%.*s'\n", 3, hello);
        printf("message: '%.*s'\n", 5, hello);
        return 0;
}

พิมพ์:

message: 'Hel'
message: 'Hel'
message: 'Hello'

11

โดยใช้printfคุณสามารถทำได้

printf("Here are the first 8 chars: %.8s\n", "A string that is more than 8 chars");

หากคุณใช้ C ++ คุณสามารถบรรลุผลลัพธ์เดียวกันโดยใช้ STL:

using namespace std; // for clarity
string s("A string that is more than 8 chars");
cout << "Here are the first 8 chars: ";
copy(s.begin(), s.begin() + 8, ostream_iterator<char>(cout));
cout << endl;

หรือมีประสิทธิภาพน้อยกว่า:

cout << "Here are the first 8 chars: " <<
        string(s.begin(), s.begin() + 8) << endl;

1
หมายเหตุ: ไม่ได้ใช้ostream_iterator<char>(cout)! ให้ใช้แทนostreambuf_iterator<char>(cout)! ความแตกต่างของประสิทธิภาพควรมีค่อนข้างมาก
Dietmar Kühl

std::cout.write(s.data(), 8)วิธีที่มีประสิทธิภาพมากขึ้นแทนที่จะใช้: หรือใน C ++ สมัยใหม่, std::cout << std::string_view{s.data(), 8}.
Artyer

4

พิมพ์อักขระสี่ตัวแรก:

printf("%.4s\n", "A string that is more than 8 chars");

ดูลิงค์นี้สำหรับข้อมูลเพิ่มเติม (ตรวจสอบ. ความแม่นยำ - ส่วน)


4

ใน C ++ นั้นเป็นเรื่องง่าย

std::copy(someStr.c_str(), someStr.c_str()+n, std::ostream_iterator<char>(std::cout, ""));

แก้ไข: นอกจากนี้ยังปลอดภัยกว่าที่จะใช้สิ่งนี้กับตัวทำซ้ำสตริงดังนั้นคุณจะไม่ทำงานจนจบ ฉันไม่แน่ใจว่าเกิดอะไรขึ้นกับ printf และสตริงที่สั้นเกินไป แต่ฉันเดาว่านี่อาจปลอดภัยกว่า


32
ฮ่าใช่ว่า "ง่าย" C ++ มักจะดูเหมือนอุบัติเหตุทางรถยนต์
ประธานเจมส์เค. โพล์

คุณยังสามารถพิมพ์ printf () ใน c ++ ได้ :)
StasM

6
ฉันคิดว่านี่คือการถากถาง std::cout << someStr.substr(0,8);ชัดเจนกว่ามาก
MSalters

2
@MSalters คุณควรโพสต์เป็นคำตอบ
Jonathan Mee


1

ใน C ++ ฉันทำในลักษณะนี้:

char *buffer = "My house is nice";
string showMsgStr(buffer, buffer + 5);
std::cout << showMsgStr << std::endl;

โปรดทราบว่าสิ่งนี้ไม่ปลอดภัยเนื่องจากเมื่อส่งอาร์กิวเมนต์ที่สองฉันสามารถเกินขนาดของสตริงและสร้างการละเมิดการเข้าถึงหน่วยความจำได้ คุณต้องดำเนินการตรวจสอบของคุณเองเพื่อหลีกเลี่ยงปัญหานี้

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