Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.98/43: Рейтинг темы: голосов - 43, средняя оценка - 4.98
18 / 18 / 5
Регистрация: 08.10.2009
Сообщений: 94
1

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

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


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

Как сделать это средствами c++?
Среда Visual Studio 2010
Заранее благодарен
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.07.2011, 23:47
Ответы с готовыми решениями:

Дан текстовый файл, содержащий целые числа. Определить в каждой четной строке максимальное число и записать результаты в новый текстовый файл
Дан текстовый файл, содержащий целые числа. Определить в каждой четной строке максимальное число и...

Дан текстовый файл. Заменить окончание ing каждого слова, встречающегося в заданном предложении на ED и сохранить результат в новый файл.
Всем вечер добрый. Хотелось бы, чтоб кто-нибудь помог с прогой. Её текст ниже: Дан текстовый...

Дано число k (< 10) и текстовый файл, содержащий более k строк. Создать новый текстовый файл, содержащий k последних строк исходного файла
Дано число k (&lt; 10) и текстовый файл, содержащий более k строк. Создать новый текстовый файл,...

Файл: Есть 5 классов, как их записать в текстовый файл?
Ребята пожалуйста кто знает как разобраться с файлами. Есть 5 классов как их записать в текстовый...

__________________
Помогаю в написании студенческих работ здесь.
Записывайтесь на профессиональные курсы C++ разработчиков
14
932 / 757 / 299
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
14.07.2011, 16:14 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;
}
0
Эксперт С++
2193 / 1611 / 254
Регистрация: 29.05.2011
Сообщений: 3,306
14.07.2011, 16:17 3
Такой метод наверняка нерабочий.
Из рабочих первое что приходит в голову — использовать библиотеку iconv (хотя здесь хватило бы одноимённой утилиты)
0
4851 / 3272 / 466
Регистрация: 10.12.2008
Сообщений: 10,570
15.07.2011, 10:27 4
Цитата Сообщение от Neonjke
Есть текстовый файл в UTF-8
Нужно рядом сохранить его же, но в ANSI
а ansi - это что ?

вообще utf-8 и ascii выглядят одинаково в первых 256 символах
0
Эксперт С++
2193 / 1611 / 254
Регистрация: 29.05.2011
Сообщений: 3,306
15.07.2011, 11:55 5
Цитата Сообщение от accept Посмотреть сообщение
вообще utf-8 и ascii выглядят одинаково в первых 256 символах
Не может быть!
Только первые 128. Дальше UTF-8 двухбайтовый и более.
0
1220 / 854 / 184
Регистрация: 16.03.2008
Сообщений: 4,076
Записей в блоге: 1
15.07.2011, 15:02 6
Цитата Сообщение от accept Посмотреть сообщение
вообще utf-8 и ascii выглядят одинаково в первых 256 символах
почему тогда вывод
C++
1
printf("%d",'ю');
будет разным на системах с разной локалью?
0
2226 / 1729 / 865
Регистрация: 21.12.2010
Сообщений: 3,073
Записей в блоге: 11
15.07.2011, 16:08 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;
}
0
4851 / 3272 / 466
Регистрация: 10.12.2008
Сообщений: 10,570
16.07.2011, 07:13 8
Цитата Сообщение от grizlik78
Только первые 128. Дальше UTF-8 двухбайтовый и более.
это я перепутал с unicode

Цитата Сообщение от voral
почему тогда вывод будет разным на системах с разной локалью?
ю не входит в ascii
0
2821 / 1630 / 252
Регистрация: 03.12.2007
Сообщений: 4,222
16.07.2011, 22:12 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);
}
0
4851 / 3272 / 466
Регистрация: 10.12.2008
Сообщений: 10,570
17.07.2011, 05:23 10
похоже, что раскодируемые символы нужно писать напрямую, а те, которые не входят в ascii, писать в виде вопросиков
при этом нужно различать вопрос и нераспознанный символ
0
1769 / 747 / 153
Регистрация: 03.06.2009
Сообщений: 5,283
17.07.2011, 09:13 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
1
4851 / 3272 / 466
Регистрация: 10.12.2008
Сообщений: 10,570
18.07.2011, 03:06 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
(всё равно не все показывает)
0
Вложения
Тип файла: zip utf8toascii.zip (1.3 Кб, 26 просмотров)
4851 / 3272 / 466
Регистрация: 10.12.2008
Сообщений: 10,570
18.07.2011, 05:25 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]$
0
Вложения
Тип файла: zip utf8toascii.zip (1.4 Кб, 36 просмотров)
Эксперт С++
2193 / 1611 / 254
Регистрация: 29.05.2011
Сообщений: 3,306
19.07.2011, 01:19 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;
}
0
0 / 0 / 0
Регистрация: 15.11.2013
Сообщений: 8
30.11.2013, 13:33 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 )
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.11.2013, 13:33

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

Файл: Скопировать текст в другой текстовый файл файл, но чётные строки должны быть с большой буквы...
Создать текстовый файл. Скопировать текст в другой текстовый файл файл, но чётные строки должны...

Даны натуральное , символьный файл и текстовый файл . Файл содержит 30 слов , каждое из которых будем называть ключевым
Добрый день, помогите пожалуйста сделать вот такую программу. Даны натуральное k , символьный файл...

Создать текстовый файл из 5 строк, прочитать созданный файл и получить новый файл согласно своему варианту. Dev C++
8)В новом файле заменить все латинские буквы верхнего регистра на буквы нижнего регистра.

Текстовый файл перевести в двоичный, а потом полученный двоичный файл перевести обратно в текстовый
Всем привет. Есть такая задачка: &quot;текстовый файл перевести в двоичный, а потом полученный двоичный...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.