printf#
כותב מחרוזת מפורמטת למטפל קובץ.
printf הוא print FILEHANDLE sprintf(FORMAT, LIST) עם חריג אחד מכוון: מפריד רשומות הפלט $\ אינו מצורף. כללי היעד הם בכל מקרה כללי print - bareword או סקלר פשוט כמטפל קובץ ממש לפני רשימת הארגומנטים, או צורת הבלוק {EXPR} עבור כל דבר מורכב יותר. אם FILEHANDLE מושמט, הפלט הולך למטפל הנבחר כעת (ראו select), שמתחיל את חייו כ־STDOUT.
ראו sprintf לעיון במציין הפורמט - כל ה־%d, %s, %.3f, %*d, %1$s, %v, דגלי ווקטור, %f הרגיש ל־locale, וכן הלאה. עמוד זה מכסה רק את המשטח הייחודי ל־printf: פתרון מטפל הקובץ, כלל הפורמט־ראשון, וההתנהגויות המוזרות סביב הצורה ללא־ארגומנטים.
תקציר#
printf FORMAT, LIST
printf FILEHANDLE FORMAT, LIST
printf {EXPR} FORMAT, LIST
printf FH # bareword filehandle, $_ as format
מה מקבלים בחזרה#
1 בהצלחה, undef בכשל (כאשר $! נקבע). כמו ב־print, ערך ההחזרה נבדק לעיתים נדירות עבור כתיבות ל־STDOUT / STDERR, וכדאי לבדוק אותו עבור כתיבות לקבצים, pipes, וסוקטים שבהם כתיבות חלקיות ו־pipes שבורים חשובים.
printf $fh "%-20s %8d\n", $name, $count
or die "write to $path failed: $!";
מצב גלובלי שהוא נוגע בו#
מטפל הקובץ הנבחר (משתנה דרך
select): היעד כאשרFILEHANDLEמושמט. מתחיל כ־STDOUT.$\(מפריד רשומות הפלט): אינו מצורף בכוונה - זהו ההבדל הסמנטי היחיד ביןprintf FORMAT, LISTלביןprint FILEHANDLE sprintf(FORMAT, LIST). שימו את השורה החדשה במחרוזת הפורמט.$,(מפריד שדות הפלט): אינו נלקח בחשבון.printfמשלב את אלמנטי הרשימה לתוך הפורמט בהתאם להמרות, לא באמצעות מפריד.$_: משמש כפורמט כאשר גםFORMATוגםLISTמושמטים, לא מצורף לפלט. כמעט אף פעם לא מה שאתם רוצים; ראו מקרי קצה.$!: נקבע בכשל כתיבה.$|: דגל autoflush עבור המטפל הנבחר.printfמשתמש ב־buffering דרך PerlIO כמוprint.locale
LC_NUMERIC: כאשרuse localeפעיל ו־POSIX::setlocaleנקרא, מפריד הנקודה העשרונית להמרות נקודה־צפה (%f,%e,%g) עוקב אחרי ה־locale.
דוגמאות#
כתיבה מפורמטת בסיסית ל־STDOUT. בניגוד ל־say או ל־print־עם־$\, השורה החדשה הסופית באחריותכם:
printf "%s is %d years old\n", $name, $age;
רוחב ודיוק עבור עמודה מסודרת:
printf "%-20s %8.2f\n", $item, $price;
כתיבה למטפל קובץ. bareword וסקלר פשוט עובדים ישירות; ללא פסיק בין מטפל הקובץ לפורמט:
open my $fh, ">", "report.txt" or die $!;
printf $fh "%5d %s\n", $n, $msg;
close $fh;
מטפל קובץ המוחזק בביטוי מורכב יותר - השתמשו בצורת הבלוק {EXPR} (אותו כלל כמו ב־print):
my @logs = (\*STDOUT, \*STDERR);
printf { $logs[$severity] } "[%s] %s\n", $tag, $msg;
פורמט חוזר עם רשימה המשתרעת על־פני מספר רשומות. printf אינו מיישם מחדש את הפורמט לכל רשומה - המרות נצרכות פעם אחת, משמאל לימין:
printf "%s=%s\n", "user", "alice"; # "user=alice\n"
printf "%s=%s\n%s=%s\n", # two records, one call
"user", "alice", "host", "db1";
מפריד נקודה עשרונית רגיש ל־locale:
use POSIX qw(setlocale LC_NUMERIC);
use locale;
setlocale(LC_NUMERIC, "de_DE.UTF-8");
printf "%.2f\n", 1234.5; # "1234,50\n"
מקרי קצה#
LISTלא נמסר,$_הופך לפורמט.printf;ו־printf FH;(מטפל קובץ כ־bareword) מפרמטים את$_. אם$_מכיל המרות%כלשהן הן מתפרשות כנגד רשימת ארגומנטים ריקה - כל%s/%dהופך למחרוזת הריקה ו־use warningsפולט אזהרתMissing argument in printf. כדי לכתוב את$_ככתבו וכלשונו השתמשו ב־print, לא ב־printf.מטפל קובץ עקיף ללא רשימה הוא עמום ואינו נתמך.
printf $fh;מפרסר את$fhכפורמט, לא כמטפל הקובץ. אם אתם צריכים צורה ללא־ארגומנטים עם מטפל קובץ סקלרי, עברו דרךprintאו העבירו פורמט מפורש:printf $fh "%s", $_.הארגומנט הראשון הוא תמיד הפורמט.
printf(@_)משתמש ב־$_[0]כפורמט ובאלמנטים הנותרים כארגומנטים - זהו כלל פרסור, לא מוסכמה. בנו את הפורמט בכוונה; אל תשטחו רשימות שנמסרו על־ידי המשתמש לתוךprintfאלא אם האלמנט הראשון ידוע כבטוח.$\אינו מצורף. הטמעת"\n"בפורמט היא המסיים האידיומטי. קביעתlocal $\ = "\n"אינה משפיעה על פלטprintf.$,מתעלמים ממנו. מפריד שדות הפלט הוא מושג שלprint;printfאינו מצרף דבר - הוא מחליף.printf (…)מתפרסר כקריאת פונקציה, בדיוק כמוprint.printf ("%d", 1)*2מחשב אתprintf(...)ואז כופל את ערך ההחזרה ב־2ומשליך אותו. עטפו את כל רשימת הארגומנטים בסוגריים או הקדימו ב־+אם צריך לפענח את העמימות.מטפל קובץ סגור: מחזיר
undefוקובע את$!ל־"Bad file descriptor". תחתuse warningsנפלטת אזהרתprintf() on closed filehandle.שכבות קידוד:
printfכותב דרך מחסנית PerlIO של המטפל. שכבת:utf8או:encoding(...)מקודדת בדרך החוצה; מטפל במצב־בתים עם מחרוזת תווים רחבים פולטWide character in printfוכותב נקודות קוד גולמיות.SIGPIPEעל pipe/סוקט סגורים: פעולת ברירת המחדל מסיימת את התהליך. התקינו$SIG{PIPE}כדי להפוך זאת לכשל כתיבה שניתן לבדוק.אל תשתמשו ב־
printfכאשרprintמספיק.printf "%s", $msgאיטי יותר ונוטה לשגיאות יותר מ־print $msg- מחרוזת הפורמט נפרסרת בכל קריאה, ו־%נדודה ב־$msgהמשמשת כפורמט הופכת לבאג שמחכה לקרות.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
print- כתיבה לא־מפורמטת עם אותם כללי מטפל קובץ; מהיר יותר, ומצרף את$\במקום ש־printfאינו מצרףsprintf- בונה את המחרוזת המפורמטת מבלי לכתוב אותה; עיון מציין הפורמט נמצא כאןsay-printעם$\המאולץ ל־"\n"; בחרו בו כאשר כל רשומה מסתיימת בשורה חדשהselect- שנו לאיזה מטפל קובץ הצורה ללא־מטפל־קובץ שלprintfכותבת$\- מפריד רשומות הפלט; אינו מצורף בכוונה על־ידיprintf$_- משמש כפורמט כאשר גםFORMATוגםLISTמושמטים