LINUX.ORG.RU

gcc символьный массив ERROR!!!


0

2
#include<iostream>
using namespace std;
int main()
{

        char A [19];
        string s="В начале было слово";

        for (int i=0; i<19; i++)
                A[i]=s[i];
        for (int i=0; i<19; i++)
                cout<<A[i];

        cout<<endl;
        return 0;
}

Вывод: В начале б(тут символ неизвестного символа (знак вопроса в квадратике));

Под виндой выводит всю строку нормально. ЧЯДНТ?

запускаю под geany выводит просто «В начале б» без символа.

mrXorg ()

Oh my God! My eyes! MY EYES!!

anonymous ()

Очевидно же: s[i] возвращает один байт строки, когда символы занимают по 2 байта.

gentoo_root ★★★★★ ()
Ответ на: комментарий от visual

1. char A [4096]; зачем, скажи пожалуйста если не трудно. 2. если я хочу вывести из массива только букву б, как я ее должен выводить? Я просто не пойму принцип действия( Просто книгу еще не читал на счет этого, а лабу уже надо делать(((

mrXorg ()
Ответ на: комментарий от mrXorg

Компилятор пишет строковую константу согласно локали, емнип.
Соответственно в винде получаем какой-нибудь cp1251 и всё хорошо выводится, а в юниксе получаем utf-8, где каждая буква весит по 2 байта (utf-8).

anonymous ()
Ответ на: комментарий от mrXorg

есть разница между однобайтными кодировками и многобайтными. В данном случае используется, скорее всего, UTF-8. При данной кодировке один символ может занимать от одного до шести байт (шесть - это экзотика, но тем не менее возможно). Поэтому при копировании первых 19 байт из UTF-8 строки «В начале было слово» будет скопировано «В начале б?»
Каждый символ кириллицы (за исключением пробела) занимаеи по два байта. Ищите в интернете информацию про многобайтные кодировки (и UTF-8 в частности), про то, как с ними работать (какие стандартные функции есть) и как конвертировать текст из одной кодировки в другую.

Slavaz ★★★★★ ()
Ответ на: комментарий от Slavaz

блин, если пробелы по 1 байту, то тогда работать с массивом очень тяжело. Ведь надо знать количество перед символом который хочешь вывести получается((

mrXorg ()
#include <iostream>
#include <string>
using namespace std;
int main()
{
    string s = "В начале было слово";
    int ssize = s.size();
    cout << "// в исходной строке " << ssize << " байт, евпочя" << endl;
    char *A = new char[ssize];
    for (int i = 0; i < ssize; i++) {
        A[i] = s[i];
    }
    for (int i = 0; i < ssize; i++) {
        cout << A[i];
    }
    cout << endl;
    delete[] A;
}
anonymous ()

#include<iostream>
using namespace std;
int main()
{
wchar_t char A;
wstring s=L"В начале было слово";

for(wstring::iterator i = s.begin(); i!= s.end(); i++) {
A = *i;
wcout << A;
}

cout<<endl;
return 0;
}

Например.

anonymous ()
Ответ на: комментарий от anonymous
#include <iostream>
#include <string>
using namespace std;
int main()
{
    string s = "В начале было слово";
    int ssize = s.size();
    cout << "// в исходной строке " << ssize << " байт, евпочя" << endl;
    char *A = new char[ssize+1];       // быстрофикс
    for (int i = 0; i < ssize; i++) {
        A[i] = s[i];
    }
    A[ssize] = 0;                      // быстрофикс
    for (int i = 0; i < ssize; i++) {
        cout << A[i];
    }
    cout << endl;
    delete[] A;
}
anonymous ()
Ответ на: комментарий от anonymous

Быстроподнятое не считается упавшим?

anonymous ()
Ответ на: комментарий от visual

cat /proc/meminfo

MemTotal: 1025080 kB
MemFree: 110888 kB

Иду ва-банк:

char A[113549312];

ttnl ★★★★★ ()
Ответ на: комментарий от anonymous

Кстати «фикс» даже ещё веселее, чем оригинал.
Хочу третий вариант!

anonymous ()

тема решена

не оффтопьте ###################

mrXorg ()
Ответ на: комментарий от visual

>char A[113549313];

Не катит. Ва-банк только ва-банком бъется )

ttnl ★★★★★ ()
Ответ на: комментарий от mrXorg

если есть желание работать с UTF-8 строкой как с массивом, то сначала нужно перевести строку в UCS-32 , в которой каждый символ превратится в 4 байта. тогда можно будет спокойно обращаться к символам как к элементам массива.

Slavaz ★★★★★ ()
Ответ на: комментарий от visual

что делать, чтобы как в винде работало? Я поменял кодировку в geany на windows-1251 но не робит

mrXorg ()
Ответ на: комментарий от Slavaz

спасибо, желания нету, как сделать чтобы как под виндой было?

mrXorg ()
Ответ на: комментарий от mrXorg

Какой еще оффтоп? Люди тут тебе массив подбирают, а ты еще обижаешься!

Pavval ★★★★★ ()
Ответ на: комментарий от mrXorg

на windows-1251 но не робит

терминал не знает данной кодировки?

mrXorg ()

подскажите пожалуйста как сделать, чтобы 1 символ = 1 байту был

mrXorg ()
Ответ на: комментарий от mrXorg

Ну надо не забыть ещё компилятору сказать, что строки надо в однобайтовой кодировке писать.
Эта зараза GCC упорно их в UTF пишет.
Где-то ключик был, надо в мане смотреть.

anonymous ()
Ответ на: комментарий от mrXorg

> спасибо, желания нету, как сделать чтобы как под виндой было?

Если не планируется никаких других символов, кроме русской кириллицы, то можно просто конвертнуть текст в любую однобайтную кодировку (KOI8-R, CP1251, IBM-866, ISO-8859-5) и работать «как под виндой». По окончании работы надо будет опять перевести в UTF-8, чтобы нормально отобразить на экране.

P.S. Это совсем неправильный путь, но если задача слишком узкоспециализирована и/или одноразовая, то вполне подойдёт и это решение.

P.P.S. как именно перекодировать текст:
man 3 iconv

Slavaz ★★★★★ ()
Ответ на: комментарий от Slavaz

Да, в догонку: дабы полностью работать «как под виндой» (stricmp и прочее регистронезависимое) нужно ещё man setlocale почитать :)

Slavaz ★★★★★ ()
Ответ на: комментарий от Slavaz

сделал кодировку ISO-8859-5, перепечатал текст - выводит только знаки вопросов вместо букв

mrXorg ()
Ответ на: комментарий от anonymous

-fexec-charset=charset

это то, в какой кодировке он строковые константы будет в исполняемый файл писать.

Это сильно неправильно всё, конечно. Но раз хочется.

anonymous ()
Ответ на: комментарий от anonymous

Ну то есть
-fexec-charset=charset
-finput-charset=charset

'charset' привести в соответствие с текущей локалью (кои8, допустим). И в такой же кодировке, естественно, исходник должен быть.

anonymous ()
Ответ на: комментарий от mrXorg

> UCS-32LE и UCS-32BE есть, но ругается компилятор на них

Ну вообще-то в UCS лучше конвертировать из системной кодировки (в данном случае из UTF-8), а не изначально хранить в этой кодировке.

ну если есть желание сразу хранить так, то: -fexec-charset=UCS4

Slavaz ★★★★★ ()
Ответ на: комментарий от mrXorg

> сделал кодировку ISO-8859-5, перепечатал текст - выводит только знаки вопросов вместо букв
правильно. терминал не понимает ISO-8859-5.
надо назад в UTF-8 перегонять перед печатью на экран

Slavaz ★★★★★ ()
Ответ на: комментарий от Slavaz

перегоняю назад в ютф8, печатается снова «В начале б?»

mrXorg ()
Ответ на: комментарий от Slavaz

вы имеете ввиду, надо заполнить массив используя ISO-8859-5 и потом перед печатью программно вывести уже через ютф8?

mrXorg ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.