Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.94/18: Рейтинг темы: голосов - 18, средняя оценка - 4.94
0 / 0 / 0
Регистрация: 29.08.2016
Сообщений: 19

Почему-то не читается содержимое файла в OEM 866 на других компах, кроме моего

03.10.2016, 19:28. Показов 3896. Ответов 36

Студворк — интернет-сервис помощи студентам
Всем привет!

Я написал программку по считыванию файла в формате OEM 866 и выводе определенных строк в консоль. На моих компьютерах все работает отлично, однако на других компьютерах содержимое файла попросту не читается, но при этом сам файл открывается без проблем (добавил функцию проверки is_open). Разница между компьютерами в установленном GCC.

Подскажите, пожалуйста, какие библиотеки нужно добавить, дабы все читалось без проблем без установки GCC? На данный момент в проекте есть libgcc_s_dw2-1.dll и libstdc++-6.dll.

Заметка, программа читает нормально файлы в кодировке Windows 1251 на любых компах.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
03.10.2016, 19:28
Ответы с готовыми решениями:

Программа не работает на всех компах кроме моего
Добрый день. Создал проект, программа работает нормально. Решил вытащить exe файл, чтобы скинуть проверить на других компах, ну и знакомым...

В папке Сеть 11 других компьютеров кроме моего
Здраствуйте , на днях зашел в папку ''Сеть'' и обноружил там 11 других компьютеров кроме моего. Вопрос 1:Так должно быть или нет ? ...

Вывод текста в кодировке Win-1251 из bat-файла, текст которого в кодировке OEM-866
примем за аксиому утверждение: "bat-скрипт следует создавать в кодировке DOS (OEM-866)" ...пусть в скрипте есть код, который...

36
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
04.10.2016, 23:25
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от FrankieRafie Посмотреть сообщение
Да, тут и на компах, где работает, прописана bin папка компилятора.
Там, где не работает, не прописана, и никогда не стоял ни этот mingw, ни другой?

Добавлено через 3 минуты
Чтобы время сократить, нужно заодно ещё такое проверить. Если будет выводить считанное, то значит не находит в считанном. Тогда нужно проверить, как выводится на консоль текст из кода, и как он выглядит на консоли после функции CharToOem().
0
0 / 0 / 0
Регистрация: 29.08.2016
Сообщений: 19
04.10.2016, 23:33  [ТС]
Там где не работает, не прописан путь и никогда не стоял никакой компилятор это точно.

Добавлено через 7 минут
T.e.
C++
1
2
3
char domain_on_ch[28];
    CharToOem("Конфигурация профиля Domain", domain_on_ch);
cout<<domain_on_ch<<endl;
???

Или что ты имеешь ввиду?
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
04.10.2016, 23:36
Цитата Сообщение от FrankieRafie Посмотреть сообщение
Или что ты имеешь ввиду?
Вот код (из редактора Code Blocks, возьми его, тот предыдущий код был из редактора студии, мало ли что). Только скрин, там где не работает сделай, чтобы были видны две верхние строчки на консоли при выводе (если конечно вывод будет). И чтобы буфера консоли хватило, чтобы верхние строчки не сожрались.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
void NetworkInfo(string path)
{
    //setlocale(0, "");
    string str;
    ifstream fin(path.c_str());
    if (!fin.is_open())
    {
        cout << "Can't open NetworkInfo file"<<endl;
        return;
    }
 
 
    bool have_DNS=false, is_wifi=false, domain_on=false, standart_on=false, is_router=false;
    size_t found;
    char domain_on_ch[28];
    CharToOem("Конфигурация профиля Domain", domain_on_ch);
 
    cout << "Конфигурация профиля Domain" << endl;
    cout << domain_on_ch << endl << endl;
 
    char is_wifi_ch[36];
    CharToOem("Адаптер беспроводной локальной сети", is_wifi_ch);
    char standart_on_ch[24];
    CharToOem("Конфигурация профиля Об", standart_on_ch);
    char is_router_ch[11];
    CharToOem("IPv4-адрес", is_router_ch);
    char public_ch[12];
    CharToOem("DNS-серверы", public_ch);
    vector<string> DNSstr;
    size_t i = 1;
    while(!fin.eof())
    {
        getline(fin, str);
        cout << i++ << ' ' << str << endl;
        found = str.find(is_wifi_ch);
        if (found!=std::string::npos)
            is_wifi=true;
        found = str.find(is_router_ch);
        if (found!=std::string::npos)
        {
            found = str.find("192");
            if (found!=std::string::npos)
                is_router=true;
        }
        else
        {
            found = str.find("IPv4 Address");
            if (found!=std::string::npos)
            {
                found = str.find("192");
                if (found!=std::string::npos)
                    is_router=true;
            }
        }
        found = str.find(public_ch);
        if (found!=std::string::npos)
        {
                while(true)
                {
                    DNSstr.push_back(str);
                    getline(fin, str);
                    cout << i++ << ' ' << str << endl;
                    found = str.find("NetBIOS");
                    if (found!=std::string::npos)
                        break;
                    found = str.find("NetBios");
                    if (found!=std::string::npos)
                        break;
                }
                have_DNS=true;
        }
        else
        {
            found = str.find("DNS Servers");
            if (found!=std::string::npos)
            {
                while(true)
                {
                    DNSstr.push_back(str);
                    getline(fin, str);
                    cout << i++ << ' ' << str << endl;
                    found = str.find("NetBIOS");
                    if (found!=std::string::npos)
                        break;
                    found = str.find("NetBios");
                    if (found!=std::string::npos)
                        break;
                }
                have_DNS=true;
            }
        }
        found = str.find(domain_on_ch);
        if (found!=std::string::npos)
        {
                getline(fin, str);
                cout << i++ << ' ' << str << endl;
                getline(fin, str);
                cout << i++ << ' ' << str << endl;
                found = str.find("= Enable");
                if (found!=std::string::npos)
                    domain_on=true;
        }
        else
        {
            found = str.find("Domain profile configuration");
            if (found!=std::string::npos&&!domain_on)
            {
                getline(fin, str);
                cout << i++ << ' ' << str << endl;
                getline(fin, str);
                cout << i++ << ' ' << str << endl;
                found = str.find("= Enable");
                if (found!=std::string::npos)
                    domain_on=true;
            }
        }
        found = str.find(standart_on_ch);
        if (found!=std::string::npos)
        {
            cout<<endl;
            getline(fin, str);
            cout << i++ << ' ' << str << endl;
            getline(fin, str);
            cout << i++ << ' ' << str << endl;
            found = str.find("= Enable");
            if (found!=std::string::npos)
                standart_on=true;
        }
        else
        {
            found = str.find("Standard profile configuration");
            if (found!=std::string::npos)
            {
                getline(fin, str);
                cout << i++ << ' ' << str << endl;
                getline(fin, str);
                cout << i++ << ' ' << str << endl;
                found = str.find("= Enable");
                if (found!=std::string::npos)
                    standart_on=true;
            }
        }
    } // while
 
    fin.close();
    if(is_router)
        cout<<"Player use ROUTER"<<endl;
 
    if(is_wifi)
        cout<<"Player use or used WI-FI on this computer"<<endl;
 
    if(domain_on)
        cout<<"Domain's firewall is ON"<<endl;
 
    if(standart_on)
        cout<<"Standart firewall is ON"<<endl;
 
    if(have_DNS)
    {
        cout << "DNS addresses are: " << endl;
        for(int i=0;i<DNSstr.size();i++)
            cout << DNSstr[i] << endl;
    }
    else
        cout<<"Can't find DNS strings in Networkinfo"<<endl;
}
0
0 / 0 / 0
Регистрация: 29.08.2016
Сообщений: 19
04.10.2016, 23:42  [ТС]
Ок, спасибо. Тот код тоже работал. Завтра напишу, как что вышло.

Еще я поставил версию Release и убрал все опции флаги, кроме: [-O2], [-s] во флагах компилятора.
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
05.10.2016, 06:16
Цитата Сообщение от FrankieRafie Посмотреть сообщение
Еще я поставил версию Release
Лучше не нужно ничего менять, а то потом непонятно будет: что из-за чего поменялось, код в Release - это уже другой код. Да, и код нужно будет в Debug, в отладчике смотреть. Если хочется Release попробовать, то сделай и пробуй и Debug, и Release.
0
0 / 0 / 0
Регистрация: 29.08.2016
Сообщений: 19
05.10.2016, 15:25  [ТС]
Короч, затестили. Все строчки читаются, однако, все равно не находит. Строчка с OEM не выходит, char выходит, но кракозябрами. Т.е.
C++
1
2
cout << "Конфигурация профиля Domain" << endl;
    cout << domain_on_ch << endl << endl;
Показывает только первую строчку.
Второй попросту нет.

Самое интересное, что у него кракозябры на месте русского.

У меня на компе первая строка кракозябры, остальное, что в OEM нормально отображается.

Еще одно. Проверил на еще одном компе, где опять же ничего не ставилось и проги никогда не было, и оно работает! Видимо, скорее всего, проблема в настройке системы или что-то типа того.

От чего это может зависеть?
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
05.10.2016, 15:46
Цитата Сообщение от FrankieRafie Посмотреть сообщение
Все строчки читаются, однако, все равно не находит. Строчка с OEM не выходит, char выходит, но кракозябрами.
Цитата Сообщение от FrankieRafie Посмотреть сообщение
От чего это может зависеть?
Скрины сделал?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
05.10.2016, 15:57
Лучший ответ Сообщение было отмечено FrankieRafie как решение

Решение

Цитата Сообщение от FrankieRafie Посмотреть сообщение
Подскажите, пожалуйста, какие библиотеки нужно добавить, дабы все читалось без проблем без установки GCC?
GCC здесь вообще не при чем. CharToOemA конвертирует текст из системной кодировки в
кодировку консоли, совместимую с текстовым режимом (т.е. из ANSI в OEM, если простым языком).
Проблема в том, что в зависимости от локализации системы и ее региональных настроек эти
кодировки могут различаться. Например, на русских Виндах, а также там, где для программ,
не поддерживающих Unicode, установлен русский язык, системной кодировкой является CP-1251
(кириллица). Но на английских Виндах там уже CP-1252. OEM-кодировки тоже различаются,
для русского языка там OEM866, для английского другая (какая - сейчас не вспомню).

Когда ты запускаешь свою программу на английской, например, Винде, то CharToOemA
"думает", что на вход ей подают CP-1252, а на самом деле там CP-1251, вот и получаем
"кракозябры", не работающие функции поиска подстроки и т.п.
1
0 / 0 / 0
Регистрация: 29.08.2016
Сообщений: 19
05.10.2016, 17:03  [ТС]
Проблема в том, что я проверял и компилировал на русской Windows 10 64. Там все без проблем. У меня на работе Windows 7 64 английская и данная функция работает. У коллеги точно такая же Винда и все работает. А у 2-ух других коллег опять же такая винда, но не работает.

Скрины сейчас скину.

Добавлено через 19 минут
Фото с компа, где не работает. Английская Windows 7 64 bit







Фото с работающего. Английская Windows 7 64 bit





0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
05.10.2016, 17:17
Видно, что там даже шрифт другой. Выясни уже в какой кодировке консоль работает там и там. Команда chcp. И шрифты посмотри какие выбраны.
Что считается Char, а что OEM тоже надо проверить.
1
0 / 0 / 0
Регистрация: 29.08.2016
Сообщений: 19
05.10.2016, 18:21  [ТС]
У меня 866, где не работает 437.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
05.10.2016, 18:45
Цитата Сообщение от FrankieRafie Посмотреть сообщение
У меня 866, где не работает 437.
Ну так об этом же как раз и написано в #28.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
05.10.2016, 18:46
Цитата Сообщение от FrankieRafie Посмотреть сообщение
Фото с работающего. Английская Windows 7 64 bit

Она может быть английской локализации, но при этом в "региональных стандартах"
стоять русский язык для программ, не поддерживающих юникод. В этом случае
тоже все будет работать. А на "чистой" английской или другой некириллической
локализации Windows твоя программа не будет работать нормально, пока ты
ее не перепишешь на Unicode. Никакие "костыли" не помогут, только Unicode.
1
0 / 0 / 0
Регистрация: 29.08.2016
Сообщений: 19
05.10.2016, 18:54  [ТС]
Всем спасибо! С локализациями помогло. Оказалось, что на компах, где работало, для не Unicode программ стояла локализация Russian, а где не работало, стояло English. При смене на Russian все действительно работает.

Если не сложно, подскажите, пожалуйста, как в будущем можно этого избежать, работая с файлами в кодировке OEM 866?

Или же какую-нибудь статейку про работу с Unicode в C++.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
05.10.2016, 21:49
Лучший ответ Сообщение было отмечено DrOffset как решение

Решение

Цитата Сообщение от FrankieRafie Посмотреть сообщение
Если не сложно, подскажите, пожалуйста, как в будущем можно этого избежать, работая с файлами в кодировке OEM 866?
Прежде всего, ты должен всегда знать, в какой кодировке у тебя текст и какая кодировка
требуется для той или иной функции. Есть такой принцип: если у тебя есть строка, но
ты не знаешь, в какой она кодировке, то можешь считать, что у тебя нет этой строки.

Это проблема очень многих компонентов и программных интерфейсов, которые работают с
текстом: они манипулируют так и сяк строками, но явно не оговаривают, в какой кодировке
должны быть эти строки; иногда "подразумевается" UTF-8, иногда системная кодировка
ANSI или еще какая-нибудь конкретная, но какая точно - никто не скажет... Отсюда и
рождаются ошибки, подобные этой. А вот если бы мы точно знали, что текст в исходном
файле в кодировке CP-1251, а для вывода нужна строго OEMCP, то можно было выполнить
соответствующее преобразование с помощью MultiByteToWideChar и WideCharToMultiByte
(сначала из CP-1251 в Unicode UTF-16, затем из него в OEMCP), либо одним из других
подходящих способов (ICU, iconv и т.п.) и это работало бы на любой системе и на
любых региональных настройках.

В Windows есть три основных кодировки:

* UTF-16 (Unicode)

Основная рабочая кодировка Windows, появилась в Windows 2000 и с тех пор она
используется практически всеми компонентами системы, включая ядро. Прелесть Unicode
объяснять не нужно: один и тот же текст, не зависимо от локализации и региональных
настроек системы, кодируется и выглядит везде одинаково. Кроме того, пространство
Unicode очень большое, оно включает в себя символы и специальные знаки подавляющего
большинства существующих алфавитов и письменностей, включая всякую для нас с вами
экзотику, такую как иероглифы, арабский язык с письмом справа-налево и т.п.
Только используя Unicode можно отобразить в одном предложении слова на разных языках
(например, сообщение на немецком языке, которое содержит имя файла с иероглифами).

* ANSI (системная кодировка)

Кодировка для поддержки программ, которые не работают с Unicode.
В зависимости от настроек и локализации системы, это может быть или CP-1251
(кириллица), или CP-1252 (латиница), или одна из множества других кодовых страниц.
Беда в том, что текст, подразумевающий дефолтную кодировку ANSI, может прекрасно
отображаться на одной системе и превращаться в "кракозябры" на другой.
Типичный пример - MessageBoxA с текстом на русском языке, который отображается
только на адаптированных под русский язык системах. У MessageBoxW такой проблемы
нет, потому что она использует Unicode (W - от "Wide Char" или "Wide String",
т.е. "широкие" символы).

* OEM (системная кодировка консоли)

Эта кодировка предназначена для использования консольными приложениями.
Также, как и ANSI, конкретная кодировка зависит от локализации и региональных
настроек системы. Русский - OEM-866, французский - OEM-863, греческий - OEM-737, и т.д.
Минусы те же: текст в OEM-кодировке переносим только на те системы, которые умеют
работать с ней. Например, чтобы заставить английскую Windows показать в консоли
текст в OEM-866, потребуется целая серия очень хитрых "приседаний".

Если нет каких-то других особых причин, я рекомендую всегда стараться использовать
только Unicode, так как это на порядок снижает количество проблем, связанных с
интернационализацией приложения. Собственно, интернационализация - это и есть
переход на Unicode, его для того и придумали.

При этом использование Unicode не освобождает тебя от ответственности все равно
знать, в какой кодировке текст Потому что там может быть UTF-8, а может
UTF-16 или UTF-32, Big или Little Endian, с BOM или без...

Конкретно у консоли в Windows есть еще один очень большой недостаток - для
отображения текста в определенной кодировке нужно еще, чтобы был установлен
"правильный" шрифт. Документированные способы программно найти и установить для
консоли подходящий шрифт существуют только на последних версиях Windows и
там все равно очень легко запутаться. Если ты не знаешь на 100%, как это сделать,
то лучше всего использовать только символы латинского алфавита и работать с
текстом в консоли только латиницей. С отображением латиницы точно уж проблем
никаких не возникнет. Многие программы именно так и поступают.
1
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
05.10.2016, 21:50
Ну просто перекодируешь содержимое файла из 866 в unicode при чтении.
Но консоль всё равно придётся настраивать - кодировку и шрифт.

Добавлено через 54 секунды
А почему не использовать нормальное приложение? Консоль так необходима?
0
0 / 0 / 0
Регистрация: 29.08.2016
Сообщений: 19
05.10.2016, 22:43  [ТС]
Спасибо за ответы.

Не использовал гуишки, так как не особо умею их писать, да и не требовалось. Пытался изучать Qt, но не смог найти нормальные гайды (видимо плохо искал). Писал программу на скорую руку для себя, дабы упростить себе работу с файлами и документами. Да и планирую специализироваться на других языках, но пока что располагаю лишь C++.

Насчет OEM 866, у нас все файлы типа NetworkInfo в кодировке OEM 866. Потому я и не ожидал такой проблемы, в связи с неопытностью.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
05.10.2016, 22:43
Помогаю со студенческими работами здесь

Кодировка OEM 866
Доброго времени суток. ђҐЈЁ®* - вот эту лабуду хотелось бы перевести в нормальный вид. Пробовал что вроде const Fn1 =...

TStringList и OEM-866
Добрый день. Столкнулся с проблемой разбивки строки по разделителю, используя TStringList. У меня есть файл с текстом в кодировке...

На вижу мой сайт на своем компе, на других компах его видно. Почему?
Прошу прощения, если не в том разделе, прошу перенести по адресу. Суть проблемы. Я создала сайт и выложила на хостинг. Мой сайт виден с...

Перекодировка из OEM-866 в Windows-1251
написан батник, результат каждой команды он выводит в лог так: 1&gt;&gt;%~dp0\log.txt 2&gt;&gt;&amp;1 понятно после завершения батника в этом логе...

Перекодировка текста из OEM 866 в UTF-8 или Ansi с загрузкой в Memo
Всем привет! Помогите пожалуйста. У меня в исходниках есть текстовые файлы в кодировке OEM 866, пытаюсь налету перекодировать содержимое...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru