C ++ هل يمكن أن يحمل Char من النوع الأصلي لشخصية الملف؟

StackOverflow https://stackoverflow.com/questions/1851525

  •  13-09-2019
  •  | 
  •  

سؤال

العنوان هو جميل التفسير الذاتي.

char c = std::cin.peek(); // sets c equal to character in stream

لقد أدركت فقط أن سحر نوع الأصلي لا يمكن أن يحمل eof.

شكرا، NMR.

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

المحلول

إجابة قصيرة: لا. استخدام إتجاه بدلا من شار.

إجابة أطول قليلا: لا. إذا كنت تستطيع الحصول على حرف أو القيمة إف من وظيفة، مثل ج غرس و c ++ نظرة خاطفة, بوضوح طبيعي شار المتغير لن يكون كافيا لعقد كل شخصيات صالحة و القيمة إف.

حتى الإجابة لفترة أطول: ذلك يعتمد، لكنها لن تعمل أبدا لأنك قد تأمل.

يحتوي C و C ++ على ثلاثة أنواع أحرف (باستثناء أنواع "واسعة"): شار, شار وقع و غير موقعة. وبعد سهل شار يمكن توقيعها أو غير موقعة، وهذا يختلف بين التحويل البرمجيات.

القيمة إف هو عدد صحيح سلبي، عادة -1، لذلك من الواضح أنه لا يمكنك تخزينه في غير موقعة أو في سهل شار هذا غير مميز. على افتراض أن نظامك يستخدم أحرفا 8 بت (التي تفعل كل شيء تقريبا)، إف سيتم تحويلها إلى (عشري) 255، ولن يعمل البرنامج الخاص بك.

ولكن إذا كان لديك شار يتم توقيع الكتابة، أو إذا كنت تستخدم شار وقع اكتب، ثم نعم، يمكنك تخزين -1 في ذلك، لذلك نعم، يمكن أن تعقد إف. وبعد ولكن ماذا يحدث بعد ذلك عندما تقرأ شخصية برمز 255 من الملف؟ سيتم تفسيره على أنه -1، وهذا هو، إف (على افتراض أن تنفيذك يستخدم -1). لذلك سيتوقف الرمز الخاص بك عن القراءة ليس فقط في نهاية الملف، ولكن أيضا بمجرد أن تجد حرفا 255.

نصائح أخرى

لاحظ أن قيمة الإرجاع لل std::cin.peek() هو في الواقع من النوع std::basic_ios<char>::int_type, ، وهذا هو نفسه std::char_traits<char>::int_type, ، وهو int وليس أ char.

أكثر أهمية من ذلك، تعاد القيمة في ذلك int ليس بالضرورة وضعا بسيطا من char ل int ولكن هو نتيجة للاتصال std::char_traits<char>::to_int_type على الحرف التالي في الدفق أو std::char_traits<char>::eof() (الذي يعرف أن يكون EOF) إذا لم يكن هناك شخصية.

عادة، يتم تنفيذ هذا كل شيء بنفس الطريقة تماما fgetc يلقي الشخصية إلى unsigned char ثم إلى int لقيمة العودة حتى تتمكن من التمييز بين جميع قيم الأحرف الصالحة EOF.

إذا قمت بتخزين قيمة الإرجاع std::cin.peek() في char ثم هناك إمكانية قراءة شخصية بقيمة إيجابية (قل ÿ في ملف مشفر ISO-8859-1) مقارنة EOF .

الشيء المحدد الذي يجب القيام به سيكون.

typedef std::istream::traits_type traits_type;

traits_type::int_type ch;
traits_type::char_type c;

while (!traits_type::eq_int_type((ch = std::cin.peek()), traits_type::eof()))
{
    c = traits_type::to_char_type(ch);
    // ...
}

ربما سيكون هذا أكثر استخداما:

int ch;
char c;

while ((ch = std::cin.peek()) != EOF)
{
    c = std::iostream::traits_type::to_char_type(ch);
    // ...
}

لاحظ أنه من المهم تحويل قيمة الأحرف بشكل صحيح. إذا قمت بإجراء مقارنة مثل هذا: if (ch == '\xff') ... أين ch هو int على النحو الوارد أعلاه، قد لا تحصل على النتائج الصحيحة. تحتاج إلى استخدام std::char_traits<char>::to_char_type على ch أو std::char_traits<char>::to_int_type على الطابع الثابت للحصول على نتيجة ثابتة. (عادة ما تكون آمنة مع أعضاء مجموعة الأحرف الأساسية، على الرغم من ذلك.)

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