Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 33, средняя оценка - 4.61
Neonjke
18 / 18 / 1
Регистрация: 08.10.2009
Сообщений: 94
#1

Текстовый файл UTF-8 сохранить как текстовый файл ANSI - C++

13.07.2011, 23:47. Просмотров 4158. Ответов 14

Есть текстовый файл в UTF-8
Нужно рядом сохранить его же, но в ANSI

Как сделать это средствами c++?
Среда Visual Studio 2010
Заранее благодарен
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.07.2011, 23:47     Текстовый файл UTF-8 сохранить как текстовый файл ANSI
Посмотрите здесь:

Дан текстовый файл. Заменить окончание ing каждого слова, встречающегося в заданном предложении на ED и сохранить результат в новый файл. C++
C++ Скопировать текстовый файл в новый файл, заменив в каждой строке слова «ok» на «*»
C++ Текстовый файл перевести в двоичный, а потом полученный двоичный файл перевести обратно в текстовый
Дан текстовый файл, содержащий целые числа. Определить в каждой четной строке максимальное число и записать результаты в новый текстовый файл C++
Даны натуральное , символьный файл и текстовый файл . Файл содержит 30 слов , каждое из которых будем называть ключевым C++
C++ Дан текстовый файл. Перепишите его в выходной файл, удалив все знаки препинания
C++ Дан исходный текстовый файл. Записать его строки в выходной файл в перевёрнутом виде
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
xAtom
913 / 738 / 60
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
14.07.2011, 16:14     Текстовый файл UTF-8 сохранить как текстовый файл ANSI #2
Вот попробуй.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <fstream.h>
#include <iostream>
using namespace std;
 
int main(void) {
 
   wfstream  fin("utf8.txt",   ios_base::in);
   fstream    fout("ansi.txt", ios_base::out);
 
   char      ansi = 0;
   while( ! fin.eof() ) {
      wctomb(&ansi, fin.get());
      fout.write(&ansi, sizeof(char));
   }
 
   fin.close();
   fout.close();
 
   cin.get();
   return 0;
}
grizlik78
Эксперт С++
1897 / 1429 / 106
Регистрация: 29.05.2011
Сообщений: 2,985
14.07.2011, 16:17     Текстовый файл UTF-8 сохранить как текстовый файл ANSI #3
Такой метод наверняка нерабочий.
Из рабочих первое что приходит в голову — использовать библиотеку iconv (хотя здесь хватило бы одноимённой утилиты)
accept
4817 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
15.07.2011, 10:27     Текстовый файл UTF-8 сохранить как текстовый файл ANSI #4
Цитата Сообщение от Neonjke
Есть текстовый файл в UTF-8
Нужно рядом сохранить его же, но в ANSI
а ansi - это что ?

вообще utf-8 и ascii выглядят одинаково в первых 256 символах
grizlik78
Эксперт С++
1897 / 1429 / 106
Регистрация: 29.05.2011
Сообщений: 2,985
15.07.2011, 11:55     Текстовый файл UTF-8 сохранить как текстовый файл ANSI #5
Цитата Сообщение от accept Посмотреть сообщение
вообще utf-8 и ascii выглядят одинаково в первых 256 символах
Не может быть!
Только первые 128. Дальше UTF-8 двухбайтовый и более.
voral
377 / 357 / 50
Регистрация: 16.03.2008
Сообщений: 1,801
15.07.2011, 15:02     Текстовый файл UTF-8 сохранить как текстовый файл ANSI #6
Цитата Сообщение от accept Посмотреть сообщение
вообще utf-8 и ascii выглядят одинаково в первых 256 символах
почему тогда вывод
C++
1
printf("%d",'ю');
будет разным на системах с разной локалью?
igorrr37
1611 / 1239 / 124
Регистрация: 21.12.2010
Сообщений: 1,895
Записей в блоге: 7
15.07.2011, 16:08     Текстовый файл UTF-8 сохранить как текстовый файл ANSI #7
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
#include <iostream>
#include <fstream>
#include <boost/archive/detail/utf8_codecvt_facet.hpp>
#include <locale>
#include <wchar.h>
#include <windows.h>
typedef boost::archive::detail::utf8_codecvt_facet ufacet;
 
int main(){
    SetConsoleOutputCP(1251);
    std::locale uloc(std::locale(), new ufacet());
    std::wifstream wifs("1.txt"); // файл utf-8
    if(!wifs){std::cerr<<"File not found\n"; return 1;}
    std::ofstream ofs("2.txt");
    wifs.imbue(uloc);
    wchar_t arr[512];
    for(size_t i=0; wifs.get(arr[i]); ++i){
        int code=(int)arr[i];
        if(code>127){
            if(code==0x401) code=-88;
            else if(code==0x451) code=-72;
            else code-=1104;
        }
        ofs<<(char)code;
    }
    wifs.close();
    ofs.close();
    return 0;
}
accept
4817 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
16.07.2011, 07:13     Текстовый файл UTF-8 сохранить как текстовый файл ANSI #8
Цитата Сообщение от grizlik78
Только первые 128. Дальше UTF-8 двухбайтовый и более.
это я перепутал с unicode

Цитата Сообщение от voral
почему тогда вывод будет разным на системах с разной локалью?
ю не входит в ascii
Somebody
2777 / 1591 / 142
Регистрация: 03.12.2007
Сообщений: 4,169
Завершенные тесты: 1
16.07.2011, 22:12     Текстовый файл UTF-8 сохранить как текстовый файл ANSI #9
Вариант с WinAPI и промежуточным UTF-16:
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
#include <fstream>
#include <vector>
#include <windows.h>
 
using namespace std;
 
int main()
{
    ifstream fin("utf8.txt", ios::in | ios::binary);
    fin.seekg(0, ios::end);
    size_t len = fin.tellg();
    fin.seekg (0, ios::beg);
    vector<char> strUtf8(len);
    fin.read(&strUtf8[0], strUtf8.size());
 
    len = MultiByteToWideChar(CP_UTF8, 0, &strUtf8[0], strUtf8.size(), 0, 0);
    vector<wchar_t> strUtf16(len);
    len = MultiByteToWideChar(CP_UTF8, 0, &strUtf8[0], strUtf8.size(), &strUtf16[0], strUtf16.size());
    if (len == 0)
        return 1;
 
    len = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR, &strUtf16[0], strUtf16.size(), 0, 0, 0, 0);
    vector<char> strAnsi(len);
    len = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR, &strUtf16[0], strUtf16.size(), &strAnsi[0], strAnsi.size(), 0, 0);
    if (len == 0)
        return 1;
 
    ofstream fout("ansi.txt", ios::out | ios::trunc | ios::binary);
    size_t pos = strUtf16[0] == 0xfeff ? 1 : 0;
    fout.write(&strAnsi[pos], strAnsi.size() - pos);
}
accept
4817 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
17.07.2011, 05:23     Текстовый файл UTF-8 сохранить как текстовый файл ANSI #10
похоже, что раскодируемые символы нужно писать напрямую, а те, которые не входят в ascii, писать в виде вопросиков
при этом нужно различать вопрос и нераспознанный символ
alexcoder
1449 / 663 / 88
Регистрация: 03.06.2009
Сообщений: 3,413
Завершенные тесты: 1
17.07.2011, 09:13     Текстовый файл UTF-8 сохранить как текстовый файл ANSI #11
Я когда-то давно перекодировал так:
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
typedef struct _XLAT{
WORD unicode;
BYTE win;
}XLAT;
XLAT chars[66]={
{0xd191,0xb8},
{0xd190,0xa8},
{0xd090,0xc0},
{0xd091,0xc1},
{0xd092,0xc2},
{0xd093,0xc3},
{0xd094,0xc4},
{0xd095,0xc5},
{0xd096,0xc6},
{0xd097,0xc7},
{0xd098,0xc8},
{0xd099,0xc9},
{0xd09a,0xca},
{0xd09b,0xcb},
{0xd09c,0xcc},
{0xd09d,0xcd},
{0xd09e,0xce},
{0xd09f,0xcf},
{0xd0a0,0xd0},
{0xd0a1,0xd1},
{0xd0a2,0xd2},
{0xd0a3,0xd3},
{0xd0a4,0xd4},
{0xd0a5,0xd5},
{0xd0a6,0xd6},
{0xd0a7,0xd7},
{0xd0a8,0xd8},
{0xd0a9,0xd9},
{0xd0aa,0xda},
{0xd0ab,0xdb},
{0xd0ac,0xdc},
{0xd0ad,0xdd},
{0xd0ae,0xde},
{0xd0af,0xdf},
{0xd0b0,0xe0},
{0xd0b1,0xe1},
{0xd0b2,0xe2},
{0xd0b3,0xe3},
{0xd0b4,0xe4},
{0xd0b5,0xe5},
{0xd0b6,0xe6},
{0xd0b7,0xe7},
{0xd0b8,0xe8},
{0xd0b9,0xe9},
{0xd0ba,0xea},
{0xd0bb,0xeb},
{0xd0bc,0xec},
{0xd0bd,0xed},
{0xd0be,0xee},
{0xd0bf,0xef},
{0xd180,0xf0},
{0xd181,0xf1},
{0xd182,0xf2},
{0xd183,0xf3},
{0xd184,0xf4},
{0xd185,0xf5},
{0xd186,0xf6},
{0xd187,0xf7},
{0xd188,0xf8},
{0xd189,0xf9},
{0xd18a,0xfa},
{0xd18b,0xfb},
{0xd18c,0xfc},
{0xd18d,0xfd},
{0xd18e,0xfe},
{0xd18f,0xff},
};
 
....
      for(x=0,y=0;x<lstrlen(newname);x++)
        {
         if(newname[x]==0xd0||newname[x]==0xd1)
            {
            WORD un;
            DWORD mm;
            un=newname[x]*256+newname[x+1];
            for(mm=0;mm<66&&chars[mm].unicode!=un;mm++);
            if(mm==66)
                {
                newname1[y]=newname[x];
                y++;
               }
            else
                {
                x++;
                newname1[y]=chars[mm].win;
                y++;
                }
            }
         else
            {
            newname1[y]=newname[x];
            y++;
            }
         }
         newname1[y]=0;
newname - строка unicode
newname1 - строка cp1251
accept
4817 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
18.07.2011, 03:06     Текстовый файл UTF-8 сохранить как текстовый файл ANSI #12
переводит файл из utf-8 в ascii, заменяя непереводимые символы специальными последовательностями
Код
[guest@localhost tests]$ .ansi t.c -o t
[guest@localhost tests]$ ./t
 normal bytes1 normal bytes1 normal bytes1 normal bytes2 bytes2 normal bytes2 bytes2 normal bytes2 bytes2 normal bytes1 normal bytes1 normal bytes1 normal bytes1 normal bytes1 normal bytes3 bytes3 bytes3 normal bytes4 bytes4 bytes4 bytes4 normal bytes2 bytes2 normal bytes1 normal bytes4 bytes4 bytes4 bytes4 normal bytes3 bytes3 bytes3 normal bytes2 bytes2 normal bytes1 normal bytes1 normal bytes3 bytes3 bytes3 normal bytes3 bytes3 bytes3 normal bytes1 normal bytes1 normal bytes2 bytes2 normal bytes3 bytes3 bytes3 normal bytes3 bytes3 bytes3 normal bytes3 bytes3 bytes3 normal bytes2 bytes2 normal bytes1
[guest@localhost tests]$ cat file.txt
abcабвdef
dງ��яd��ງк
aງງb
аງງງб
[guest@localhost tests]$ cat output.txt
abc<?2><?2><?2>def
d<?3><?4><?2>d<?4><?3><?2>
a<?3><?3>b
<?2><?3><?3><?3><?2>
[guest@localhost tests]$
нажми цитата, чтобы просмотреть символы из file.txt
(всё равно не все показывает)
Вложения
Тип файла: zip utf8toascii.zip (1.3 Кб, 22 просмотров)
accept
4817 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
18.07.2011, 05:25     Текстовый файл UTF-8 сохранить как текстовый файл ANSI #13
поправил комментарии
тот же вывод
Код
[guest@localhost tests]$ .ansi main.c -o t
[guest@localhost tests]$ ./t
 normal bytes1 normal bytes1 normal bytes1 normal bytes2 bytes2 normal bytes2 bytes2 normal bytes2 bytes2 normal bytes1 normal bytes1 normal bytes1 normal bytes1 normal bytes1 normal bytes3 bytes3 bytes3 normal bytes4 bytes4 bytes4 bytes4 normal bytes2 bytes2 normal bytes1 normal bytes4 bytes4 bytes4 bytes4 normal bytes3 bytes3 bytes3 normal bytes2 bytes2 normal bytes1 normal bytes1 normal bytes3 bytes3 bytes3 normal bytes3 bytes3 bytes3 normal bytes1 normal bytes1 normal bytes2 bytes2 normal bytes3 bytes3 bytes3 normal bytes3 bytes3 bytes3 normal bytes3 bytes3 bytes3 normal bytes2 bytes2 normal bytes1
[guest@localhost tests]$ cat file.txt
abcабвdef
dງ��яd��ງк
aງງb
аງງງб
[guest@localhost tests]$ cat output.txt
abc<?2><?2><?2>def
d<?3><?4><?2>d<?4><?3><?2>
a<?3><?3>b
<?2><?3><?3><?3><?2>
[guest@localhost tests]$
Вложения
Тип файла: zip utf8toascii.zip (1.4 Кб, 30 просмотров)
grizlik78
Эксперт С++
1897 / 1429 / 106
Регистрация: 29.05.2011
Сообщений: 2,985
19.07.2011, 01:19     Текстовый файл UTF-8 сохранить как текстовый файл ANSI #14
Мой вариант с использованием libiconv. Можно использовать разные комбинации кодировок.
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
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <iconv.h>
 
int main(void)
{
    FILE *ifp, *ofp;
    size_t inbytesleft = 0, outbytesleft, incount;
    char inbuf[BUFSIZ], outbuf[BUFSIZ];
    char *inbufptr, *outbufptr;
    iconv_t cd;
    int result = 0;
 
    /* перекодируем из UTF8 в WINDOWS-1251 */
    cd = iconv_open("WINDOWS-1251", "UTF8");
    /* вариант с пропуском неправильных последовательностей:
       cd = iconv_open("WINDOWS-1251//IGNORE", "UTF8");   */
 
    if (cd == (iconv_t)-1)
    {
        fprintf(stderr, "iconv_open error\n");
        return result;
    }
 
    ifp = fopen("file.txt", "rb");
    ofp = fopen("output.txt", "wb");
    if (NULL == ifp || NULL == ofp)
    {
        fprintf(stderr, "File open error\n");
        return 1;
    }
 
    inbytesleft = 0;
    /* заполняем свободное пространство входного буфера из файла */
    while (( incount = fread(inbuf+inbytesleft, 1, BUFSIZ - inbytesleft, ifp)) > 0)
    {
        inbytesleft += incount;
        inbufptr = inbuf;
        do { /* перекодируем порциями до тех пор,
                пока переполняется выходной буфер */
            outbytesleft = BUFSIZ;
            outbufptr = outbuf;
            errno = 0;
            iconv(cd, &inbufptr, &inbytesleft,
                    &outbufptr, &outbytesleft);
            /* схохраняем перекодированный кусок */
            if (outbufptr != outbuf)
                fwrite(outbuf, 1, outbufptr - outbuf, ofp);
        } while (E2BIG == errno);
        if (EILSEQ == errno)
        {
            /* если встретилась недопустимая последовательность выходим */
            /* можно пропускать побайтово вручную 
               или добавить суффикс //IGNORE к результирующей кодировке*/
            fprintf(stderr, "Illegal sequence\n");
            return 1;
        }
        /* перемещаем оставшуюся часть входных данных в начало*/
        if (inbytesleft > 0)
            memmove(inbuf, inbufptr, inbytesleft);
    }
 
    if (ferror(ifp) || ferror(ofp))
    {
        fprintf(stderr, "error in files\n");
        result = 1;
    }
 
    iconv_close(cd);
    fclose(ifp);
    fclose(ofp);
 
    return result;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.11.2013, 13:33     Текстовый файл UTF-8 сохранить как текстовый файл ANSI
Еще ссылки по теме:

C++ Дано число k (< 10) и текстовый файл, содержащий более k строк. Создать новый текстовый файл, содержащий k последних строк исходного файла
дан текстовый файл.определить количество нечетных чисел и записать их в др текст файл C++
C++ Задан текстовый файл, необходимо по нему сформировать двоичный файл индексов
C++ Файл: Скопировать текст в другой текстовый файл файл, но чётные строки должны быть с большой буквы...
Не получается прочесть правильно текстовый файл в структуру а затем в бинарный файл C++

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

Или воспользуйтесь поиском по форуму:
Realism_32
0 / 0 / 0
Регистрация: 15.11.2013
Сообщений: 8
30.11.2013, 13:33     Текстовый файл UTF-8 сохранить как текстовый файл ANSI #15
Цитата Сообщение от alexcoder Посмотреть сообщение
Я когда-то давно перекодировал так:
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
typedef struct _XLAT{
WORD unicode;
BYTE win;
}XLAT;
XLAT chars[66]={
{0xd191,0xb8},
{0xd190,0xa8},
{0xd090,0xc0},
{0xd091,0xc1},
{0xd092,0xc2},
{0xd093,0xc3},
{0xd094,0xc4},
{0xd095,0xc5},
{0xd096,0xc6},
{0xd097,0xc7},
{0xd098,0xc8},
{0xd099,0xc9},
{0xd09a,0xca},
{0xd09b,0xcb},
{0xd09c,0xcc},
{0xd09d,0xcd},
{0xd09e,0xce},
{0xd09f,0xcf},
{0xd0a0,0xd0},
{0xd0a1,0xd1},
{0xd0a2,0xd2},
{0xd0a3,0xd3},
{0xd0a4,0xd4},
{0xd0a5,0xd5},
{0xd0a6,0xd6},
{0xd0a7,0xd7},
{0xd0a8,0xd8},
{0xd0a9,0xd9},
{0xd0aa,0xda},
{0xd0ab,0xdb},
{0xd0ac,0xdc},
{0xd0ad,0xdd},
{0xd0ae,0xde},
{0xd0af,0xdf},
{0xd0b0,0xe0},
{0xd0b1,0xe1},
{0xd0b2,0xe2},
{0xd0b3,0xe3},
{0xd0b4,0xe4},
{0xd0b5,0xe5},
{0xd0b6,0xe6},
{0xd0b7,0xe7},
{0xd0b8,0xe8},
{0xd0b9,0xe9},
{0xd0ba,0xea},
{0xd0bb,0xeb},
{0xd0bc,0xec},
{0xd0bd,0xed},
{0xd0be,0xee},
{0xd0bf,0xef},
{0xd180,0xf0},
{0xd181,0xf1},
{0xd182,0xf2},
{0xd183,0xf3},
{0xd184,0xf4},
{0xd185,0xf5},
{0xd186,0xf6},
{0xd187,0xf7},
{0xd188,0xf8},
{0xd189,0xf9},
{0xd18a,0xfa},
{0xd18b,0xfb},
{0xd18c,0xfc},
{0xd18d,0xfd},
{0xd18e,0xfe},
{0xd18f,0xff},
};
 
....
      for(x=0,y=0;x<lstrlen(newname);x++)
        {
         if(newname[x]==0xd0||newname[x]==0xd1)
            {
            WORD un;
            DWORD mm;
            un=newname[x]*256+newname[x+1];
            for(mm=0;mm<66&&chars[mm].unicode!=un;mm++);
            if(mm==66)
                {
                newname1[y]=newname[x];
                y++;
               }
            else
                {
                x++;
                newname1[y]=chars[mm].win;
                y++;
                }
            }
         else
            {
            newname1[y]=newname[x];
            y++;
            }
         }
         newname1[y]=0;
newname - строка unicode
newname1 - строка cp1251
alexcoder, здравствуйте
А можете весь код показать? Он был бы для мне сейчас просто спасительным.
Пишу работу по переводу из utf-8 в коi-8. Сделал два этапа - из ср1251 в koi-8 и из utf-8 в unicode.

третью неделю догнать не могу как проще и лучше ее сделать (проблема в том, что нельзя пользоваться ни iconv библиотекой, ни выхватить winapi )
Yandex
Объявления
30.11.2013, 13:33     Текстовый файл UTF-8 сохранить как текстовый файл ANSI
Ответ Создать тему
Опции темы

Текущее время: 22:46. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru