סקלרים ומחרוזות

sprintf#

בניית מחרוזת מפורמטת מתבנית פורמט ורשימת ערכים.

sprintf לוקח מחרוזת FORMAT המכילה טקסט מילולי משובץ עם מציינוני המרה המוצגים על־ידי %, צורך ערכים מ־LIST כדי למלא כל מציין, ומחזיר את המחרוזת המתקבלת. זהו אותו מנגנון המניע את printf, פחות הכתיבה למטפל קובץ. Perl ממש מפרמט משלו; הוא אינו קורא ל־sprintf(3) של ספריית C פרט ליצירת ספרת הנקודה הצפה הסופית, כך שהרחבות לא־סטנדרטיות שבמקרה קיימות ב־libc שלכם אינן זמינות כאן.

תקציר#

my $s = sprintf $format, @args;
my $s = sprintf "%-10s %5d", $name, $count;
my $s = sprintf "%.3f", $x;

מה מוחזר#

מחרוזת סקלרית יחידה. לעולם לא רשימה, ללא קשר להקשר. אם FORMAT אינו מכיל מציינוני %, ערך ההחזרה הוא FORMAT ללא שינוי ו־LIST נדחית. אם FORMAT מתייחס ליותר ארגומנטים מ־LIST שמספקת, הערכים החסרים מטופלים כ־undef (אפס מספרי או מחרוזת ריקה לפי ההמרה), ואזהרת Missing argument in sprintf נורית תחת use warnings.

העברת מערך כארגומנט הראשון היא כמעט תמיד טעות - המערך מוערך בהקשר סקלרי, כך ש־Perl משתמש במונה האיברים שלו כפורמט. יש להשתמש ב־sprintf $format, @rest כשהפורמט מוחזק בנפרד, או ב־sprintf "@array" למקרה של מערך־כמחרוזת.

מצב גלובלי שהוא נוגע בו#

  • locale של LC_NUMERIC, כאשר use locale בתוקף ו־POSIX::setlocale נקראה, קובע את תו הנקודה העשרונית בשימוש על־ידי %e, %f, %g והווריאנטים הגדולים שלהם. ללא use locale הנקודה העשרונית היא תמיד ., גם אם ה־locale של התהליך אומר אחרת.

  • אף משתנה מיוחד אחר אינו נצרך. sprintf אינו קורא את $_; נדרשת רשימה מפורשת.

מציינוני המרה#

הסט המרכזי, בסדר שבו תישענו עליהם בפועל:

מציין

משמעות

%s

מחרוזת. ממיר את הארגומנט למחרוזת.

%d, %i

מספר שלם עם סימן בעשרוני. מספרי נקודה צפה נחתכים לעבר אפס.

%u

מספר שלם ללא סימן בעשרוני.

%f, %F

נקודה צפה בנקודה קבועה. ברירת מחדל 6 ספרות אחרי הנקודה העשרונית.

%e, %E

סימון מדעי. E גדול בוחר את הצורה הגדולה.

%g, %G

%e או %f, הקצר מביניהם. הדיוק הוא ספרות משמעותיות, לא ספרות אחרי הנקודה העשרונית.

%x, %X

מספר שלם ללא סימן בהקסדצימלי; %X משתמש ב־AF גדולות.

%o

מספר שלם ללא סימן באוקטלי.

%b, %B

מספר שלם ללא סימן בבינארי.

%c

תו יחיד שנקודת הקוד שלו היא המספר השלם הנתון.

%%

% מילולי. אינו צורך ארגומנט.

%p

כתובת ערך־Perl, בהקסדצימלי. לשימוש אבחוני בלבד.

%n

מאחסן את מספר התווים שנכתבו עד כה לארגומנט הבא (שחייב להיות סקלר ניתן לכתיבה).

%a, %A

נקודה צפה הקסדצימלית.

מקבילי גודל באותיות גדולות %D %U %O ו־%F קיימים לתאימות היסטורית; עדיף את הצורות הקטנות.

דגלים, רוחב, דיוק#

בין % לבין אות ההמרה, לפי הסדר:

  1. אינדקס ארגומנט - N$ בוחר את הארגומנט ה־N־י (מבוסס 1): sprintf '%2$s %1$s', 'world', 'hello' מניב "hello world".

  2. דגלים - כל צירוף של:

    • - יישור־שמאל בתוך השדה (ברירת המחדל היא יישור־ימין).

    • + הקדמת מספרים אי־שליליים ב־+.

    • ` ` (רווח) הקדמת מספרים אי־שליליים ברווח. כשנתונים גם רווח וגם +, + מנצח.

    • 0 ריפוד המרות מספריות באפסים במקום ברווחים. נדחה כאשר - נקבע גם או כשניתן דיוק עבור מספרים שלמים.

    • # צורה חלופית: קידומת 0 עבור אוקטלי, קידומת 0x/0X עבור הקסדצימלי שאינו אפס, קידומת 0b/0B עבור בינארי שאינו אפס.

  3. רוחב מינימלי - מספר עשרוני, או * כדי לקחת את הרוחב מהארגומנט הבא, או *N$ עבור ארגומנט מפורש. רוחב שלילי (דרך *) שקול לדגל -.

  4. דיוק - . ואחריו מספר עשרוני, או .* (ארגומנט הבא), או .*N$. המשמעות תלויה בהמרה:

    • %f / %e: ספרות אחרי הנקודה העשרונית (ברירת מחדל 6).

    • %g: סך הספרות המשמעותיות.

    • %d / %x / %o / %b: ספרות מינימליות; המספר מרופד באפסים לרוחב זה. הדגל 0 נדחה כאשר יש דיוק עבור מספרים שלמים.

    • %s: רוחב מקסימלי; חותך.

  5. מתאם גודל - hh, h, j, l, q, L, ll, t, z, V. מפרש את הארגומנט כטיפוס C מסוים. כמעט אף פעם לא שימושי מ־Perl - ל־Perl יש טיפוס שלם אחד וטיפוס נקודה צפה אחד, וערכים ברמת Perl אינם גולשים לגדלים שמתאמים אלה בוחרים. V היא no-op שמשמעה ״גודל ברירת המחדל של Perl״.

  6. אות המרה - אחת מערכי הטבלה לעיל.

דגל הווקטור#

קידמו את אות ההמרה ב־v (אופציונלית *v או *N$v כדי לספק מפריד) ו־Perl מתייחס לארגומנט כווקטור של נקודות קוד, מחיל את ההמרה על כל נקודת קוד ומאחה את התוצאות ב־. (או במפריד שסופק):

sprintf "%vd", "AB\x{100}";            # "65.66.256"
sprintf "%vX", "\x01\x02\x1f";         # "1.2.1F"
sprintf "%*vX", ":", "\xde\xad\xbe\xef"; # "DE:AD:BE:EF"

שימושים נפוצים: הצגת $^V, פירמוט רצפי בתים של IPv4 / IPv6, או דחיפת מחרוזות ביטים. הארגומנט נקרא תמיד כמחרוזת של נקודות קוד, לא כרשימה.

דוגמאות#

ריפוד ויישור מחרוזות בעמודת דוח ברוחב קבוע:

printf "%-10s %5d\n", "widgets", 42;   # "widgets        42\n"
printf "%-10s %5d\n", "sprockets", 7;  # "sprockets       7\n"

ריפוד באפסים של מספר שלם ברוחב קבוע, למשל עבור מפתחות מיון לקסיקוגרפיים או מספרי שורות:

sprintf "%08d", 1234;                  # "00001234"
sprintf "%05d", -7;                    # "-0007"  (sign consumes a slot)

עיגול למספר קבוע של מקומות עשרוניים. sprintf עושה את העיגול; printf היא דרך נפוצה לאלץ ערך תצוגה:

sprintf "%.3f", 3.14159265;            # "3.142"
sprintf "%.0f", 2.5;                   # "2" or "3" - banker's rounding
                                       # is platform-dependent

סימון מדעי, עם ובלי דיוק נבחר:

sprintf "%e",    6.022e23;             # "6.022000e+23"
sprintf "%.2e",  6.022e23;             # "6.02e+23"
sprintf "%g",    0.0001234;            # "0.0001234"
sprintf "%g",    0.00001234;           # "1.234e-05"  (switches to %e)

הקסדצימלי, אוקטלי ובינארי עם קידומת הצורה החלופית #:

sprintf "%#x",  255;                   # "0xff"
sprintf "%#o",  8;                     # "010"
sprintf "%#b",  10;                    # "0b1010"
sprintf "%08b", 10;                    # "00001010"   (no prefix, width 8)

תו מנקודת קוד - %c הוא בעצם chr המנותב דרך מנוע הפורמט:

sprintf "%c", 65;                      # "A"
sprintf "%c", 0x2014;                  # "-"  (em dash)

רוחב שדה מרשימת הארגומנטים - שימושי כאשר הרוחב מחושב בזמן ריצה:

my $w = 12;
sprintf "%-*s|", "name", $w;           # "name        |"

ארגומנטים מחוץ לסדר - שימושי כאשר אותו ערך מופיע מספר פעמים או כאשר פורמטים מתורגמים מסדרים מחדש מצייני־מיקום:

sprintf "%2\$s loves %1\$s", "Alice", "Bob";   # "Bob loves Alice"

בניית מחרוזת כתובת IPv4:

sprintf "%vd", "\x7f\x00\x00\x01";     # "127.0.0.1"

לכידת אורך דרך %n (הארגומנט המקבל חייב להיות סקלר ניתן לכתיבה):

my $written;
my $s = sprintf "hello%n, world", $written;
# $s       is "hello, world"
# $written is 5

מקרי קצה#

  • חיתוך מספרים שלמים ב־%d עם נקודה צפה: %d ממיר דרך כפיית מספרים שלמים, שחותכת לעבר אפס. sprintf "%d", 3.9 הוא "3", לא "4". יש להשתמש ב־%.0f אם רוצים תצוגה מעוגלת בשיטת הבנקאי, או ב־int / sprintf "%.0f" במפורש ראשון.

  • %s על עצם: ההמרה למחרוזת רצה, ועלולה להפעיל "" בהעמסה או ליפול חזרה ל־"ClassName=HASH(0x…)". אין דרך לדכא העמסה בתוך sprintf; יש לקרוא ל־overload::StrVal($obj) ראשון אם נדרשת הצורה הגולמית.

  • ארגומנטים חסרים: sprintf "%s %s", "one" מחזיר "one " ומזהיר Missing argument in sprintf at תחת use warnings. לא נזרקת חריגה.

  • יותר מדי ארגומנטים: עודפים נדחים בשקט. ללא אזהרה.

  • %s עם דיוק חותך, %d עם דיוק מרפד באפסים. sprintf "%.3s", "abcdef" הוא "abc". sprintf "%.3d", 7 הוא "007".

  • דגל %0 מול דיוק על מספרים שלמים: הדיוק מנצח. sprintf "%05.3d", 7 הוא "  007", לא "00007" - הדגל 0 נדחה ברגע שנותנים דיוק שלם מפורש.

  • רוחב שלילי דרך *: sprintf "%*s", -6, "x" הוא "x     ". דיוק שלילי דרך .* נחשב ללא־דיוק כלל.

  • NaN ו־Inf: sprintf "%f", 9**9**9 מניב "Inf"; sprintf "%f", -sin(9**9**9) מניב "NaN". האיות המדויק ("Inf" מול "inf", "NaN" מול "nan") עוקב אחר מוסכמת בניית ה־Perl, לא ההבחנה הרישית בין %f / %F.

  • נקודה עשרונית של locale: עם use locale ו־locale של de_DE, sprintf "%.2f", 1.5 יכול להפיק "1,50". ללא use locale התוצאה היא תמיד "1.50". קוד שכותב פלט מספרי לצריכה על־ידי תוכניות אחרות צריך או להימנע מ־use locale בתחום ההוא או להשתמש ב־use locale ':not_characters' ולפרמט מספרים מחוץ להשפעת ה־locale.

  • %p הוא לאבחון בלבד: ערך המצביע ההקסדצימלי משתנה מהרצה להרצה ומשולל משמעות מחוץ לתהליך הרץ. אין להשתמש בו כמפתח זהות - שתי הפניות עלולות לחלוק את אותה כתובת לאחר שהראשונה שוחררה.

  • מערך שמועבר כ־FORMAT: sprintf @a מפרמט באמצעות המונה הסקלרי של @a כמחרוזת הפורמט. כמעט תמיד באג. תמיד יש לשמור את הפורמט בסקלר משלו.

  • מתאם גודל לא־נתמך: בפלטפורמות חסרות, למשל, long double, הגודל L/q/ll בהמרת נקודה צפה נופל חזרה בשקט לגודל ברירת המחדל, ואזהרת printf נורית תחת use warnings. כדי לקדם זאת לחריגה, יש להשתמש ב־use warnings FATAL => 'printf'.

הבדלים מהמעלה־הזרם#

תאימות מלאה עם Perl 5.42 מהמעלה־הזרם.

ראו גם#

  • printf - אותו מנוע פירמוט, אך כותב למטפל קובץ במקום להחזיר את המחרוזת

  • print - לשימוש עם תוצאת sprintf בנויה־מראש כאשר רוצים לפרמט פעם אחת ולכתוב למספר מטפלים

  • chr - נקודת קוד יחידה לתו יחיד; שקול ל־sprintf "%c", $n

  • hex, oct - פעולות הפוכות: פרסור מחרוזת בהקסדצימלי/אוקטלי/בינארי בחזרה למספר

  • pack - בניית מחרוזת בינארית מתבנית; יש להישען עליו כשהפלט הוא בתים, לא פורמט הקריא לאדם

  • $_ - לא נצרך על־ידי sprintf; בניגוד לפונקציות מובנות רבות הוא תמיד צריך רשימה מפורשת