sscanf(3)

الاسم
sscanf, vsscanf - تحويل تنسيق سلسلة محارف الإدخال

المكتبة
مكتبة سي المعيارية (libc، -lc)

موجز
#include <stdio.h>

int sscanf(const char *restrict str,
           const char *restrict format, ...);

#include <stdarg.h>

int vsscanf(const char *restrict str,
           const char *restrict format, va_list ap);

    متطلبات ماكروات اختبار الميزات لـ glibc (انظر feature_test_macros(7)):

vsscanf():
    _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L

الوصف
عائلة الدوال sscanf() تفحص الإدخال المنسق وفقًا لـ format كما هو موصوف أدناه. قد يحتوي هذا التنسيق على مواصفات تحويل؛ تُخزَّن نتائج هذه التحويلات، إن وُجدت، في المواقع التي تشير إليها وسائط المؤشر التي تلي format. يجب أن تكون كل وسيطة مؤشر من نوع مناسب للقيمة التي تُرجعها مواصفة التحويل المقابلة.

إذا تجاوز عدد مواصفات التحويل في format عدد وسائط المؤشر، تكون النتائج غير محددة. إذا تجاوز عدد وسائط المؤشر عدد مواصفات التحويل، فتُقيَّم وسائط المؤشر الزائدة، ولكنها تُتجاهل بخلاف ذلك.

sscanf() تقرأ هذه الدوال إدخالها من سلسلة المحارف التي يشير إليها str.

الدالة vsscanf() مماثلة لـ vsprintf(3).

تتكون سلسلة محارف format من سلسلة من التوجيهات التي تصف كيفية معالجة سلسلة محارف الإدخال. إذا فشلت معالجة توجيه، لا يُقرأ أي إدخال إضافي، وتُرجع sscanf(). يمكن أن يكون "الفشل" أحد الأمرين التاليين: فشل إدخال، بمعنى أن محارف الإدخال لم تكن متاحة، أو فشل مطابقة، بمعنى أن الإدخال كان غير مناسب (انظر أدناه).

التوجيه هو أحد ما يلي:

•   سلسلة من محارف المسافة البيضاء (مسافة، علامة تبويب، سطر جديد، إلخ؛ انظر isspace(3)). يطابق هذا التوجيه أي مقدار من المسافة البيضاء، بما في ذلك عدم وجودها، في الإدخال.

•   محرف عادي (أي غير المسافة البيضاء أو '%'). يجب أن يطابق هذا المحرف تمامًا المحرف التالي للإدخال.

•   مواصفة تحويل، تبدأ بمحرف '%' (النسبة المئوية). تُحوَّل سلسلة من المحارف من الإدخال وفقًا لهذه المواصفة، ويُوضع الناتج في وسيطة المؤشر المقابلة. إذا لم يطابق العنصر التالي من الإدخال مواصفة التحويل، يفشل التحويل—وهذا هو فشل مطابقة.

تبدأ كل مواصفة تحويل في format إما بالمحرف '%' أو بتسلسل المحارف "%n$" (انظر أدناه للتمييز) متبوعًا بـ:

•   محرف '*' اختياري لكبت التعيين: تقرأ sscanf() الإدخال كما هو موجه بواسطة مواصفة التحويل، ولكنها تتجاهل الإدخال. لا تُطلب وسيطة مؤشر مقابلة، ولا تُدرج هذه المواصفة في عدد التعيينات الناجحة التي تُرجعها sscanf().

•   للتحويلات العشرية، محرف اقتباس اختياري ('). يحدد هذا أن رقم الإدخال قد يتضمن فواصل الآلاف كما هو معرف بواسطة فئة LC_NUMERIC من الإعدادات المحلية الحالية. (انظر setlocale(3).) قد يسبق محرف الاقتباس أو يتبع محرف كبت التعيين '*'.

•   محرف 'm' اختياري. يُستخدم هذا مع تحويلات السلاسل (%s, %c, %[)، ويُريح المستدعي من الحاجة إلى تخصيص مخبأ مطابق لحفظ الإدخال: بدلاً من ذلك، تخصص sscanf() مخبأً بحجم كافٍ، وتُسند عنوان هذا المخبأ إلى وسيطة المؤشر المقابلة، والتي يجب أن تكون مؤشرًا لمتغير char * (لا يحتاج هذا المتغير إلى التهيئة قبل الاستدعاء). يجب على المستدعي لاحقًا تحرير هذا المخبأ باستخدام free(3) عندما لا يعود مطلوبًا.

•   عدد صحيح عشري اختياري يحدد أقصى عرض حقل. يتوقف قراءة المحارف إما عند الوصول إلى هذا الحد الأقصى أو عند العثور على محرف غير مطابق، أيهما يحدث أولاً. تتجاهل معظم التحويلات محارف المسافة البيضاء الأولية (الاستثناءات مذكورة أدناه)، ولا تُحتسب هذه المحارف المُتجاهلة ضمن أقصى عرض حقل. تخزِّن تحويلات إدخال السلاسل بايتًا ختاميًا صفريًا ('\0') لتمييز نهاية الإدخال؛ لا يتضمن أقصى عرض حقل هذا المُنهي. تتطلب بعض التحويلات بالضبط عدد المحارف المحدد في أقصى عرض حقل، أو تفشل.

•   محرف مُعدِّل نوع اختياري. على سبيل المثال، يُستخدم مُعدِّل النوع l مع تحويلات الأعداد الصحيحة مثل %d لتحديد أن وسيطة المؤشر المقابلة تشير إلى long بدلاً من مؤشر إلى int.

•   مُحدِّد تحويل يحدد نوع تحويل الإدخال الذي سيُجرى.

مواصفات التحويل في format تكون على شكلين، إما تبدأ بـ '%' أو تبدأ بـ "%n$". لا ينبغي خلط الشكلين في نفس سلسلة format، إلا أن سلسلة تحتوي على مواصفات "%n$" يمكن أن تتضمن %% و %*. إذا احتوت format على مواصفات '%'، فإنها تتوافق بالترتيب مع وسائط pointer المتعاقبة. في الشكل "%n$" (المحدد في POSIX.1-2001، وليس C99)، n هو عدد صحيح عشري يحدد أن المُدخل المُحوّل يجب وضعه في الموقع المشار إليه بواسطة وسيط pointer رقم n التالي لـ format.

  التحويلات
يمكن أن تظهر محارف مُعدِّل النوع التالية في مواصفة تحويل:

h   يشير إلى أن التحويل سيكون أحد d أو i أو o أو u أو x أو X أو n، والمؤشر التالي هو مؤشر إلى short أو unsigned short (بدلاً من int).

hh  كما هو الحال مع h، لكن المؤشر التالي هو مؤشر إلى signed char أو unsigned char.

j   كما هو الحال مع h، لكن المؤشر التالي هو مؤشر إلى intmax_t أو uintmax_t. هذا المُعدِّل أُدخل في C99.

l   يشير إما إلى أن التحويل سيكون أحد d أو i أو o أو u أو x أو X أو n، والمؤشر التالي هو مؤشر إلى long أو unsigned long (بدلاً من int)، أو أن التحويل سيكون أحد e أو f أو g، والمؤشر التالي هو مؤشر إلى double (بدلاً من float). إذا استُخدم مع %c أو %s، يُعتبر المُعامل المقابل مؤشرًا إلى محرف عريض أو سلسلة محارف عريضة على التوالي.

ll  (إل-إل) يشير إلى أن التحويل سيكون أحد b أو d أو i أو o أو u أو x أو X أو n، والمؤشر التالي هو مؤشر إلى long long أو unsigned long long (بدلاً من int).

L   يشير إلى أن التحويل سيكون إما e أو f أو g، والمؤشر التالي هو مؤشر إلى long double أو (كإضافة GNU) سيكون التحويل d أو i أو o أو u أو x، والمؤشر التالي هو مؤشر إلى long long.

q   مكافئ لـ L. هذا المُحدِّد غير موجود في ANSI C.

t   كما هو الحال مع h، لكن المؤشر التالي هو مؤشر إلى ptrdiff_t. هذا المُعدِّل أُدخل في C99.

wN  تحويل عدد صحيح لاحق يقابل عدداً صحيحاً بعرض N بت (C23).

z   كما هو الحال مع h، لكن المؤشر التالي هو مؤشر إلى size_t. هذا المُعدِّل أُدخل في C99.

مُحدِّدات التحويل التالية متاحة:

%   يطابق حرف '%' حرفيًا. أي أن %% في سلسلة التنسيق يطابق حرف إدخال واحد '%'. لا يُجرى أي تحويل (لكن تُتجاهل محارف المسافات البيضاء الأولية)، ولا يحدث إسناد.

d   يطابق عددًا صحيحًا عشريًا مع إشارة اختيارية؛ يجب أن يكون المؤشر التالي مؤشرًا إلى int.

i   يطابق عددًا صحيحًا مع إشارة اختيارية؛ يجب أن يكون المؤشر التالي مؤشرًا إلى int. يُقرأ العدد الصحيح في الأساس 16 إذا بدأ بـ 0x أو 0X، وفي الأساس 8 إذا بدأ بـ 0، وفي الأساس 10 خلاف ذلك. تُستخدم فقط المحارف التي تتوافق مع الأساس.

o   يطابق عددًا صحيحًا ثمانيًا غير مع إشارة؛ يجب أن يكون المؤشر التالي مؤشرًا إلى unsigned int.

u   يطابق عددًا صحيحًا عشريًا غير مع إشارة؛ يجب أن يكون المؤشر التالي مؤشرًا إلى unsigned int.

x   يطابق عددًا صحيحًا سداسيًا عشريًا غير مع إشارة (قد يبدأ اختياريًا ببادئة 0x أو 0X، والتي تُتجاهل)؛ يجب أن يكون المؤشر التالي مؤشرًا إلى unsigned int.

X   مكافئ لـ x.

f   يطابق عددًا عائمًا مُوقَّعًا اختياريًا؛ يجب أن يكون المؤشر التالي مؤشرًا إلى float.

e   مكافئ لـ f.

g   مكافئ لـ f.

E   مكافئ لـ f.

a   (C99) مكافئ لـ f.

s   يطابق تسلسلاً من المحارف غير البيضاء؛ يجب أن يكون المؤشر التالي مؤشرًا إلى العنصر الأولي لمصفوفة محارف طويلة بما يكفي لاستيعاب تسلسل الإدخال والبايت الصفري الختامي ('\0')، الذي يُضاف آليًا. تتوقف سلسلة الإدخال عند المسافة البيضاء أو عند أقصى عرض حقل، أيهما يحدث أولاً.

c   يطابق تسلسلاً من المحارف يُحدد طوله بواسطة أقصى عرض حقل (مبدئي 1)؛ يجب أن يكون المؤشر التالي مؤشرًا إلى char، ويجب أن تكون هناك مساحة كافية لجميع المحارف (لا يُضاف بايت صفري ختامي). يُلغى التخطي المعتاد للمسافة البيضاء البادئة. لتخطي المسافة البيضاء أولاً، استخدم مسافة صريحة في التنسيق. ينجح هذا التحويل فقط إذا أمكن مطابقة عدد المحارف المُحدد بواسطة أقصى حقل.

[   يطابق تسلسلاً غير فارغ من المحارف من المجموعة المُحددة من المحارف المقبولة؛ يجب أن يكون المؤشر التالي مؤشرًا إلى char، ويجب أن تكون هناك مساحة كافية لجميع المحارف في السلسلة، بالإضافة إلى بايت صفري ختامي. يُلغى التخطي المعتاد للمسافة البيضاء البادئة. تتكون السلسلة من محارف في (أو غير موجودة في) مجموعة معينة؛ تُعرف المجموعة بالمحارف بين محرف القوس المفتوح [ ومحرف القوس المغلق ]. تستبعد المجموعة تستبعد تلك المحارف إذا كان المحرف الأول بعد القوس المفتوح هو علامة الإقحام (^). لتضمين قوس مغلق في المجموعة، اجعله المحرف الأول بعد القوس المفتوح أو علامة الإقحام؛ أي موضع آخر سينهي المجموعة. محرف الوصلة - هو أيضًا خاص؛ عند وضعه بين محرفين آخرين، يُضيف جميع المحارف المتوسطة إلى المجموعة. لتضمين وصلة، اجعلها آخر محرف قبل القوس المغلق النهائي. على سبيل المثال، [^]0-9-] تعني المجموعة "كل شيء باستثناء القوس المغلق، صفر حتى تسعة، والوصلة". تنتهي السلسلة بظهور محرف ليس في (أو، مع علامة الإقحام، في) المجموعة أو عندما ينفد عرض الحقل.

p   يطابق قيمة مؤشر (كما تُطبع بواسطة %p في printf(3))؛ يجب أن يكون المؤشر التالي مؤشرًا إلى مؤشر إلى void.

n   لا يُتوقع شيء؛ بدلاً من ذلك، يُخزَّن عدد المحارف المستهلكة حتى الآن من الإدخال عبر المؤشر التالي، الذي يجب أن يكون مؤشرًا إلى int، أو متغيرًا يتطابق حجمه مع مُعدِّل طول العدد الصحيح (المُقدم اختياريًا). هذا ليس تحويلاً ولا يزيد العدد الذي تُرجعه الدالة. يمكن إلغاء الإسناد باستخدام محرف إلغاء الإسناد *، لكن التأثير على القيمة المُرجعة غير مُحدد. لذلك لا ينبغي استخدام تحويلات %*n.

قيمة الإرجاع
عند النجاح، تعيد هذه الدوال عدد عناصر المدخلات التي طابقت وجرى تعيينها بنجاح؛ وقد يكون هذا العدد أقل من المزود، أو حتى صفرًا في حالة فشل المطابقة المبكر.

تُرجع القيمة EOF إذا تم الوصول إلى نهاية الإدخال قبل حدوث أول تحويل ناجح أو فشل مطابقة.

الأخطاء

EILSEQ
    تسلسل بايتات الدخل لا يشكل محرفاً صالحاً.

EINVAL
    لا توجد وسائط كافية؛ أو أن التنسيق format هو NULL.

ENOMEM
    نفدت الذاكرة.

السمات
للاطلاع على شرح للمصطلحات المستخدمة في هذا القسم، انظر attributes(7).
الواجهة | السمة | القيمة
sscanf(), vsscanf() | سلامة الخيوط | المنطقة (locale) آمنة لتعدد المسالك (MT-Safe)

المعايير
C11, POSIX.1-2008.

التاريخ
C89, POSIX.1-2001.

مُحدِّد q هو تدوين 4.4BSD لـ long long، بينما ll أو استخدام L في تحويلات الأعداد الصحيحة هو تدوين GNU.

إصدار Linux لهذه الدوال يعتمد على مكتبة GNU libio. اطّلع على توثيق info(1) لـ GNU libc (glibc-1.08) للحصول على وصف أكثر إيجازًا.

ملاحظات

  مُعدِّل إسناد-تخصيص 'a'
في الأصل، دعمت مكتبة GNU C التخصيص الديناميكي لإدخالات السلسلة (كإضافة غير قياسية) عبر محرف a. (هذه الميزة موجودة على الأقل منذ glibc 2.0.) وبالتالي، يمكن للمرء كتابة ما يلي لجعل sscanf() تخصص مخزنًا مؤقتًا لسلسلة، مع إرجاع مؤشر إلى ذلك المخزن في *buf:

    char *buf;
    sscanf(str, "%as", &buf);

كان استخدام الحرف a لهذا الغرض إشكاليًا، لأن a مُحدد أيضًا بواسطة معيار ISO C كمرادف لـ f (إدخال النقطة العائمة). بدلاً من ذلك، يُحدد POSIX.1-2008 المُعدِّل m لتخصيص الإسناد (كما هو موثق في الوصف، أعلاه).

لاحظ أن المُعدِّل a غير متاح إذا تم تجميع البرنامج باستخدام gcc -std=c99 أو gcc -D_ISOC99_SOURCE (ما لم يتم تحديد _GNU_SOURCE أيضًا)، وفي هذه الحالة يُفسَّر a كمُحدِّد للأعداد العائمة (انظر أعلاه).

أُضيف دعم المُعدِّل m إلى glibc 2.7، ويجب أن تستخدم البرامج الجديدة هذا المُعدِّل بدلاً من a.

بالإضافة إلى كونه مُوحَّدًا بواسطة POSIX، يتمتع المُعدِّل m بالمزايا الإضافية التالية على استخدام a:

•   يمكن أيضًا تطبيقه على محددات التحويل %c (مثلًا، %3mc).

•   يتجنب هذا الغموض فيما يتعلق بمحدد تحويل الفاصلة العائمة %a (ولا يتأثر بـ gcc -std=c99 وما إلى ذلك).

العلل

  محددات التحويل الرقمية
استخدام محددات التحويل الرقمية ينتج سلوكًا غير محدد للمدخلات غير الصالحة. انظر C11 7.21.6.2/10 (https://port70.net/%7Ensz/c/c11/n1570.html#7.21.6.2p10). هذا خطأ في معيار ISO C، وليس مشكلة تصميمية متأصلة في واجهة البرمجة. ومع ذلك، فإن التطبيقات الحالية ليست آمنة من هذا الخطأ، لذلك لا يُوصى باستخدامها. بدلًا من ذلك، ينبغي للبرامج استخدام دوال مثل strtol(3) لتحليل المدخلات الرقمية. بديلًا، يمكن التخفيف من ذلك بتحديد أقصى عرض للحقل.

  المُعدِّلات غير القياسية
هذه الدوال متوافقة تمامًا مع C99، ولكنها توفر المُعدِّلات الإضافية q و a بالإضافة إلى سلوك إضافي للمُعدِّلات L و ll. يمكن اعتبار الأخير خطأ، لأنه يُغير سلوك المُعدِّلات المُعرَّفة في C99.

بعض التركيبات من مُعدِّلات النوع ومحددات التحويل المُعرَّفة بواسطة C99 لا معنى لها (مثلًا، %Ld). بينما قد يكون لها سلوك محدد جيدًا على لينكس، فإن هذا ليس ضروريًا على الأنظمة الأخرى. لذلك من الأفضل عادةً استخدام مُعدِّلات غير مُعرَّفة بواسطة C99 على الإطلاق، أي استخدام q بدلًا من L مع تحويلات d و i و o و u و x و X أو ll.

استخدام q ليس هو نفسه كما في 4.4BSD، حيث يمكن استخدامه في تحويلات الفاصلة العائمة بشكل مكافئ لـ L.

أمثلة
لاستخدام محدد تحويل التخصيص الديناميكي، حدد m كمُعدِّل طول (وبالتالي %ms أو %m[range]). يجب على المستدعي تحرير السلسلة المُرجَعة باستخدام free(3)، كما في المثال التالي:

    char *p;
    int n;

    errno = 0;
    n = sscanf(str, "%m[a-z]", &p);
    if (n == 1) {
        printf("read: %s\n", p);
        free(p);
    } else if (errno != 0) {
        perror("sscanf");
    } else {
        fprintf(stderr, "No matching characters\n");
    }

كما هو موضح في المثال أعلاه، من الضروري استدعاء free(3) فقط إذا قرأت استدعاء sscanf() سلسلة محارف بنجاح.

انظر أيضًا
getc(3)، printf(3)، setlocale(3)، strtod(3)، strtol(3)، strtoul(3)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.