سؤال

لقد واجهت بعض الكود وكنت أتساءل ما كان المطور الأصلي قد يصل إلى. فيما يلي برنامج مبسط باستخدام هذا النمط:

      #include <stdio.h>

      int main()  {     

      char title[80] = "mytitle";      
      char title2[80] = "mayataiatale";      
      char mystring[80]; 

      /* hugh ? */
      sscanf(title,"%[^a]",mystring);
      printf("%s\n",mystring); /* Output is "mytitle" */


      /* hugh ? */
      sscanf(title2,"%[^a]",mystring); /* Output is "m" */
      printf("%s\n",mystring);


      return 0;  
  }

ال صفحة الرجل ل SCANF لديه معلومات ذات صلة، ولكن أواجه مشكلة في قراءة ذلك. ما هو الغرض من استخدام هذا النوع من الترميز؟ ما الذي يحاول تحقيقه؟

هل كانت مفيدة؟

المحلول

السبب الرئيسي لفئات الأحرف هو بحيث يتوقف تدوين٪ S في أول حرف مساحة بيضاء، حتى لو حددت أطوال الحقول، وغالبا ما تريد ذلك. في هذه الحالة، يمكن أن يكون تدوين فئة الشخصية مفيدا للغاية.

النظر في هذا الرمز لقراءة خط يصل إلى 10 أحرف، وتخلص من أي فائض، ولكن حفظ المسافات:

#include <ctype.h>
#include <stdio.h>

int main(void)
{
    char buffer[10+1] = "";
    int rc;
    while ((rc = scanf("%10[^\n]%*[^\n]", buffer)) >= 0)
    {
            int c = getchar();
            printf("rc = %d\n", rc);
            if (rc >= 0)
                    printf("buffer = <<%s>>\n", buffer);
            buffer[0] = '\0';
    }
    printf("rc = %d\n", rc);
    return(0);
}

كان هذا في الواقع رمز مثال لمناقشة حول COMP.LANG.C.Moderated (حوالي يونيو 2004) المتعلقة getline() المتغيرات.


على الأقل بعض الارتباك يسود. أول محدد تنسيق، %10[^\n], ، يقرأ ما يصل إلى 10 أحرف غير خطية ويتم تعيينها إلى المخزن المؤقت، جنبا إلى جنب مع فارغة خالية. محدد الشكل الثاني، %*[^\n] يحتوي على حرف قمع المهمة (*) ويقرأ صفر أو أكثر من الأحرف غير الخطية الباقية من المدخلات. عندما scanf() تكمل الدالة، والإدخال يشير إلى حرف جديد التالي. يقرأ جسم الحلقة ويطبع تلك الشخصية، بحيث عند إعادة تشغيل الحلقة، فإن الإدخال ينظر إلى بداية السطر التالي. العملية ثم تكرر. إذا كان الخط أقصر من 10 أحرف، فسيتم نسخ هذه الأحرف إلى المخزن المؤقت، وعمليات "الصفر أو أكثر من غير نيوتولوك" عمليات صفر غير مؤتمر الأولي.

نصائح أخرى

بنيات مثل %[a] و %[^a] موجودة بحيث scanf() يمكن استخدامها كنوع من محلل معجمي. هذه هي نوع من مثل %s, ، ولكن بدلا من جمع فترة من الأحرف "Strongy"، فإنها تجمع فقط فترة أحرف كما هو موضح من فئة الأحرف. قد يكون هناك حالات عند الكتابة %[a-zA-Z0-9] قد تكون منطقية، لكنني لست متأكدا من أن أرى حالة استخدام مقنعة للفئات التكميلية مع scanf().

IMHO، scanf() هي ببساطة ليست الأداة المناسبة لهذه الوظيفة. في كل مرة حددتها لاستخدام واحدة من ميزاتها الأكثر قوة، انتهى بي الأمر في نهاية المطاف تمزيقها وتنفيذ القدرة بطريقة مختلفة. في بعض الحالات التي تعني استخدام lex لكتابة محلل حقيقي معجمي، ولكن عادة ما تفعل خط في وقت واحد / س وكسره خشن في الرموز strtok() قبل إجراء تحويل القيمة كان كافيا.

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

انها مثل مجموعات الأحرف من التعبيرات العادية؛ [0-9] يطابق سلسلة من الأرقام، [^aeiou] يطابق أي شيء ليس حرفا صغيرا، إلخ.

هناك كل أنواع الاستخدامات، مثل سحب الأرقام والمعرفات والقطع من Whitespace، إلخ.

يمكنك أن تقرأ عنها في ISO / IEC9899 قياسي متوفر على الانترنت.

فيما يلي فقرة اقتبس من المستند [ (صفحة 286):

يطابق تسلسل غير قادر من الأحرف من مجموعة من الأحرف المتوقعة.

يتضمن جهاز التحويل جميع الأحرف اللاحقة في سلسلة التنسيق، وما يصل إلى بما في ذلك قوس الأيمن المطابق (]). تقوم الأحرف بين الأقواس (قائمة المسح الضوئي) بإنشاء العاشات، ما لم تكن الحرف بعد القوس الأيسر عبارة عن حذيفة (^)، وفي هذه الحالة تحتوي العاشات على جميع الأحرف التي لا تظهر في قائمة المسح الضوئي بين الحيلية والقوس الأيمن. إذا كان محدد التحويل يبدأ مع [] أو [^]، فإن حرف قوس الأيمن موجود في قائمة المسح الضوئي وحرف القوس الأيمن التالي التالي هو القوس الأيمن المطابق الذي ينهي المواصفات؛ وإلا فإن أول حرف قوس الأيمن التالي هو الذي ينتهي المواصفات. إذا كانت الحرف في قائمة المسح الضوئي وليس الأول، ولا والثاني حيث الحرف الأول هو ^، ولا الحرف الأخير، يتم تحديد السلوك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top