Подробности
[В начало]
Проблема в реализации № S0694
Краткое описание
time_get<>::do_get_weekday не всегда распознает полные названия дней недели; похожая проблема есть и в time_get<>::do_get_monthname
Подробное описание
Из описания time_get<>::do_get_weekday() и time_get<>::do_get_monthname() (22.2.5.1.2):
Effects: Reads characters starting at s until it has extracted the (perhaps abbreviated) name of a weekday or month. If it finds an abbreviation that is followed by characters that could match a full name, it continues reading until it matches the full name or fails.Однако в случае, когда полное название дня недели не является продолжением его сокращенного названия, это название не распознается функцией.
Например, в русской локали (ru_RU.iso88595) не распознается "Понедельник" как понедельник, так как его сокращением является "Пнд". Зато распознается как понедельник последовательность "Пндедельник", что неверно.
Судя по коду реализации и комментариям к нему, в функцию изначально заложено такое ограничение, что сокращенное название каждого дня недели является подстрокой его полного названия.
Аналогичная проблема имеет место для функции time_get<>::do_get_monthname().
Раздел стандарта
Linux Standard Base C++ Specification 3.2, Chapter 9. Libraries, 9.1. Interfaces for libstdcxx, который ссылается на ISO/IEC 14882: 2003 Programming languages --C++, section 22.2.5.1.2
Способ воспроизведения
- Проверьте, что локаль "ru_RU.iso88595" есть на данной системе. Если такой локали нет - добавьте её вручную.
- Соберите и запустите приведённую ниже программу-пример.
Пример
#include <stdio.h> #include <locale> #include <sstream> using namespace std; int main() { tm t; t.tm_wday = -1;//initial value locale loc("ru_RU.iso88595"); const time_get<char>& tg = use_facet<time_get<char> >(loc); // The 1st option // Monday in Russian - it is not recognized // const char* input_string = "\xbf\xde\xdd\xd5\xd4\xd5\xdb\xec\xdd\xd8\xda"; // The 2nd option // Incorrect name of weekday, but it is recognized as Monday // because it begins with the abbreviated Russian name of Monday const char* input_string = "\xbf\xdd\xd4\xd5\xd4\xd5\xdb\xec\xdd\xd8\xda"; printf("Input string is '%s'.\n", input_string); istringstream is(input_string); ios_base::iostate err = (ios_base::iostate)0; ios_base& str = is; str.imbue(loc); istreambuf_iterator<char> s = is; istreambuf_iterator<char> end; //this function call protected virtual function do_get_weekday tg.get_weekday(s, end, str, err, &t); string rest; while(s != end) rest+= *s++; printf("Rest of the string after parsing is '%s'.\n", rest.c_str()); printf("ios_base::failbit was%s set in err.\n", err & ios_base::failbit ? "" : "n't"); printf("tm_wday became %d.\n", t.tm_wday); return 0; }
Компонент
libstdc++
Принято
GCC Bugzilla 38081
Статус
Исправлено в gcc-4.5.0
[В начало]