Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Манипуляторы вывода работают по-разному в Windows и Linux  (Прочитано 17003 раз)
0 Пользователей и 1 Гость смотрят эту тему.
ruddystepa
Гость
« : 11-09-2006 12:05 » 

У меня почему-то при компиляции одного и того же кода на платформах Windows и Linux манипуляторы работают по разному. Например такая программа:

Код:
int main() {
    char sel;
    do{
        cout<<"Введите данные о среднемесячном траффике:\n";
        putdata(aver4month, 12);
        cout<<"Введите текущие даные об траффике за каждый месяц: \n";
        putdata(curr4month, 12);
        cout<<"Сравнительная таблица траффика за последний год: \n";
        showtable(aver4month, curr4month, 12);
        cout<<"Чтобы продолжить нажмите Y, для выхода нажмите любую букву >";
        cin>>sel;
        cout<<endl;
    }while(sel=='Y' || sel=='y');
    return 0;
}
char* getmonth(int i) {
    char* temp;
    switch(i) {
        case 0:
            temp="Январь";
            break;
        case 1:
            temp="Февраль";
            break;
        case 2:
            temp="Март";
            break;
        case 3:
            temp="Апрель";
            break;
        case 4:
            temp="Май";
            break;
        case 5:
            temp="Июнь";
            break;
        case 6:
            temp="Июль";
            break;
        case 7:
            temp="Август";
            break;
        case 8:
            temp="Сентябрь";
            break;
        case 9:
            temp="Октябрь";
            break;
        case 10:
            temp="Ноябрь";
            break;
        case 11:
            temp="Декабрь";
            break;
        default:
            temp="Неверный номер месяца!";
    }
    return temp;
}
void putdata(int mas[], int sizemas) {
    for(int i=0; i<sizemas; i++) {
        cout<<"Введите данные за "<<getmonth(i)<<" месяц > ";
        cin>>mas[i];}
}
void showtable(int masaver[], int mascurr[], int size) {
    cout<<setw(15)<<"Месяц"<<" | ";
    cout<<setw(20)<<"Средний траффик"<<" | ";
    cout<<setw(15)<<"В текущем году"<<" | ";
    cout<<setw(10)<<"Разница"<<endl;
    for(int i=0; i<size; i++) {
        cout<<setw(15)<<getmonth(i)<<" | ";
        cout<<setw(20)<<masaver[i]<<" | ";
        cout<<setw(15)<<mascurr[i]<<" | ";
        cout<<setw(10)<<(mascurr[i]-masaver[i])<<endl;
    }

Компилирую в Visual Studio 2005, запускаю - выдает аккуратную табличку, как и задумывалось. Компилю в Linux (правда, в Linux для создания make файла я пользуюсь утилитой qmake -не силен я в создании make файлов вручную Жаль( ). Запускаю - все сторочки таблицы съехали относительно друг друга. Почему? Может под линухом надо как-то по-другому применять манипуляторы?
« Последнее редактирование: 13-12-2007 19:35 от Алексей1153++ » Записан
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #1 : 11-09-2006 12:27 » 

А может дело, банально, в шрифте ?
Записан

Удачного всем кодинга! -=x[PooH]x=-
ruddystepa
Гость
« Ответ #2 : 11-09-2006 13:07 » 

А может дело, банально, в шрифте ?
Не понял, причем здесь шрифт? Ведь манипулятор setw() определяет ширину поля для выводимого выражения. Если строка не влезает в это поле, выводится та часть строки, которая влезет. Во всяком случае так написано в книжках, которые я читал.
Записан
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #3 : 11-09-2006 13:50 » 

как ты определяешь, что "все сторочки таблицы съехали относительно друг друга"? визуально?
Записан

Удачного всем кодинга! -=x[PooH]x=-
andrystepa
Помогающий

ru
Offline Offline

« Ответ #4 : 11-09-2006 16:31 » 

В общем, на экране это выглядит примерно так:
Сравнительная таблица траффика за последний год:
     Месяц | Средний траффик | В текущем году | Разница
   Январь |                  150 |             160 |         10
 Февраль |                  230 |             170 |        -60
       Март |                  124 |             178 |         54
   Апрель |                  135 |             196 |         61
         Май |                  180 |             211 |         31
       Июнь |                  178 |             188 |         10
       Июль |                  158 |             176 |         18
   Август |                  180 |             156 |        -24
Сентябрь |                  192 |             194 |          2
 Октябрь |                  211 |             200 |        -11
   Ноябрь |                  213 |             211 |         -2
 Декабрь |                  198 |             188 |        -10

только сдвиги еще больше.


« Последнее редактирование: 13-12-2007 19:36 от Алексей1153++ » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #5 : 11-09-2006 16:59 » 

Я прогнал твой код. Если все надписи в таблице заменить с русского языка на Английский, то выравнивание происходит нормально.

А теперь об ошибках
Код:
    for(int i=0; i<size; i++) {
        cout<<setw(15)<<getmonth(i)<<" | ";
        cout<<setw(20)<<masaver<<" | ";
        cout<<setw(15)<<mascurr<<" | ";
        cout<<setw(10)<<(mascurr-masaver)<<endl;
    }
Переменные masaver и mascurr явно массивы. В твоем случае должна идти распечатка адреса на массив, а не содержимое массива.

Код:
void putdata(int mas[], int sizemas) {
    for(int i=0; i<sizemas; i++) {
        cout<<"Введите данные за "<<getmonth(i)<<" месяц > ";
        cin>>mas;}
}
Тут таже проблема с переменной mas.

Теперь Твою подпрограмму с наименованием месяца можно написать намного кратче.
Завести такой массивчик:
Код:
char month[12][10]={"Januar", "February", "March", "April",
                 "May", "June", "July", "August", "September",
                    "November", "December"};
Ну и применение:
Код:
cout<<setw(15)<<month[i] <<" | ";
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #6 : 11-09-2006 17:43 » 

Это мои предположения, поэтому могу и ошибаться. В Линуксе используется кодировка UTF-8. Нижняя часть (символы от 0 и до 127) ASCII таблици полностью повторяются в данной кодировке. На каждый символ отводится 1 байт. Поэтому проблем нет с работой латинского шрифта.
Если самый верхний бит поднят. То на символ отводится уже два байта. Русский текст в Линуксе идет по два байта на каждый символ. Тут стандартная функция библиотеки сталкивается с проблемой подсчета количества символов. Поэтому она вообше никак не считает.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 11-09-2006 18:18 » 

Finch, хм. Я бы не утверждал так. Используемая кодировка определяется локалью. Ф-ии стандартной библиотеки должны ратотать согласно локали и utf8 тут не может испортить. Конечно, если используется смесь сильно разных библиотек (с поддержкой utf и без), то возможен любой эффект.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #8 : 11-09-2006 18:36 » 

RXL, Вот код, Который я получил у себя на машине, когда прогонял пример:
Код:
#include <iostream>
#include <iomanip>

char month[12][25]={"Январь", "Февраль", "March", "April",
                 "May", "June", "July", "August", "September",
                    "November", "December"};

using namespace std;

int aver4month[12];
int curr4month[12];
void putdata(int mas[], int sizemas);
void showtable(int masaver[], int mascurr[], int size);

int main() {
    char sel;
    do{
        cout<<"Введите данные о среднемесячном траффике:\n";
        //putdata(aver4month, 12);
        cout<<"Введите текущие даные об траффике за каждый месяц: \n";
        //putdata(curr4month, 12);
        cout<<"Сравнительная таблица траффика за последний год: \n";
        showtable(aver4month, curr4month, 12);
        cout<<"Чтобы продолжить нажмите Y, для выхода нажмите любую букву >";
        //cin>>sel;
sel='n';
        cout<<endl;
    }while(sel=='Y' || sel=='y');
    return 0;
}

void putdata(int mas[], int sizemas)
{
    for(int i=0; i<sizemas; i++)
{
        cout<<"Введите данные за "<<getmonth(i)<<" месяц > ";
        cin >> mas[i];
}
}
void showtable(int masaver[], int mascurr[], int size)
{
    cout << setw(15) << "Month" << " | ";
    cout<<setw(20)<<"Средний траффик"<<" | ";
    cout<<setw(15)<<"В текущем году"<<" | ";
    cout<<setw(10)<<"Разница"<<endl;
    for(int i=0; i<size; i++)
{
        cout<<setw(15)<<month[i] <<" | ";
        cout<<setw(20)<<masaver[i]<<" | ";
        cout<<setw(15)<<mascurr[i]<<" | ";
        cout<<setw(10)<<(mascurr[i]-masaver[i])<<endl;
    }
}

Я закоментил команды: чтобы сразу выводилась таблица. Ну и сразу происходил выход из проги. Я думал сначало свалить все на настройки терминала. Но прогнал прогу в текстовом терминале, таже картинка.
« Последнее редактирование: 13-12-2007 19:37 от Алексей1153++ » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 11-09-2006 18:56 » 

Да, зря я снес 5-ю Федору - сейчас бы протестил - там все заточено под utf8. Под рукой только ASP10 - на нем и попробую.

Не компилиться:
Код:
t1.cpp: In function `void putdata(int*, int)':
t1.cpp:36: error: `getmonth' undeclared (first use this function)
t1.cpp:36: error: (Each undeclared identifier is reported only once for each
   function it appears in.)
Ты наверно не все привел...
« Последнее редактирование: 13-12-2007 19:38 от Алексей1153++ » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #10 : 11-09-2006 19:02 » 

А ну правильно, Улыбаюсь Замени эту фкнкцию
Код:
void putdata(int mas[], int sizemas)
{
    for(int i=0; i<sizemas; i++)
{
        cout<<"Введите данные за "<<month[i]<<" месяц > ";
        cin >> mas[i];
}
}
Я просто снес функцию выдачи названия месяца. А тут забыл подправить.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 11-09-2006 19:14 » 

Код:
Введите данные о среднемесячном траффике:
Введите текущие даные об траффике за каждый месяц:
Сравнительная таблица траффика за последний год:
          Month |      Средний траффик |  В текущем году |    Разница
         Январь |                    0 |               0 |          0
        Февраль |                    0 |               0 |          0
          March |                    0 |               0 |          0
          April |                    0 |               0 |          0
            May |                    0 |               0 |          0
           June |                    0 |               0 |          0
           July |                    0 |               0 |          0
         August |                    0 |               0 |          0
      September |                    0 |               0 |          0
       November |                    0 |               0 |          0
       December |                    0 |               0 |          0
                |                    0 |               0 |          0
Чтобы продолжить нажмите Y, для выхода нажмите любую букву >
Локаль - ru_RU.KOI8-R.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #12 : 11-09-2006 19:17 » 

У меня дает
Код:
Введите данные о среднемесячном траффике:
Введите текущие даные об траффике за каждый месяц:
Сравнительная таблица траффика за последний год:
          Month | Средний траффик | В текущем году | Разница
   Январь |                    0 |               0 |          0
 Февраль |                    0 |               0 |          0
          March |                    0 |               0 |          0
          April |                    0 |               0 |          0
            May |                    0 |               0 |          0
           June |                    0 |               0 |          0
           July |                    0 |               0 |          0
         August |                    0 |               0 |          0
      September |                    0 |               0 |          0
       November |                    0 |               0 |          0
       December |                    0 |               0 |          0
                |                    0 |               0 |          0
Чтобы продолжить нажмите Y, для выхода нажмите любую букву >
Локаль UTF-8
« Последнее редактирование: 11-09-2006 19:19 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #13 : 11-09-2006 19:25 » 

Finch, учитывая, что число "проглоченных" пробелов равно числу кириллических символов - логично это связать.
У тебя какая локаль, какая ОС?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #14 : 11-09-2006 19:33 » 

Я тоже подумал сейчас про количество проглоченных пробелов Улыбаюсь.  У меня Ubuntu. Гномовский терминал. Сейчас терминал переключил на KOI-8,  ну и соответственно поменял кодировку сырца на КОИ и перекомпилировал. Получилась таже картинка, что и у тебя.   
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
ruddystepa
Гость
« Ответ #15 : 11-09-2006 19:58 » 

Я прогнал твой код. Если все надписи в таблице заменить с русского языка на Английский, то выравнивание происходит нормально.

А теперь об ошибках
Код:
    for(int i=0; i<size; i++) {
        cout<<setw(15)<<getmonth(i)<<" | ";
        cout<<setw(20)<<masaver<<" | ";
        cout<<setw(15)<<mascurr<<" | ";
        cout<<setw(10)<<(mascurr-masaver)<<endl;
    }
Переменные masaver и mascurr явно массивы. В твоем случае должна идти распечатка адреса на массив, а не содержимое массива.

Код:
void putdata(int mas[], int sizemas) {
    for(int i=0; i<sizemas; i++) {
        cout<<"Введите данные за "<<getmonth(i)<<" месяц > ";
        cin>>mas;}
}
Тут таже проблема с переменной mas.

Теперь Твою подпрограмму с наименованием месяца можно написать намного кратче.
Завести такой массивчик:
Код:
char month[12][10]={"Januar", "February", "March", "April",
                 "May", "June", "July", "August", "September",
                    "November", "December"};
Ну и применение:
Код:
cout<<setw(15)<<month[i] <<" | ";

Чудны дела Твои, Господи!!! Вообще-то при создании топика я копировал текст программы при помощи Copy - Paste, и куда при этом делись при вызове массивов, я не могу понять. Естественно, в оригинале стояли masaver и т.д. Иначе программа если бы и заработала, то выдала бы полную белиберду! А она выдавала все правильно, только вот с форматированием вывода... Кстати, когда сейчас я попытался скопировать текст программы в этот ответ, то при нажатии кнопки "Предпросмотр" опять пропали!!! Улыбаюсь. Что бы это значило?! Улыбаюсь).
Записан
ruddystepa
Гость
« Ответ #16 : 11-09-2006 20:01 » 

Елки палки!! Куда пропадают буквы i в квадратных скобках?! Это что, служебные символы??
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #17 : 11-09-2006 20:07 » 

ruddystepa, Все правильно Улыбаюсь Это bb коды оформления текстов на форумах. Чтобы таких приколов не случалось, обрамляй код в тэг [code( Тут твой код [/code]
Прочти эту статью https://club.shelek.ru/viewart.php?id=274 Тут описываются все остальные тэги для оформления текста.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
ruddystepa
Гость
« Ответ #18 : 11-09-2006 20:24 » 

ruddystepa, Все правильно Улыбаюсь Это bb коды оформления текстов на форумах. Чтобы таких приколов не случалось, обрамляй код в тэг [code( Тут твой код [/code]
Прочти эту статью https://club.shelek.ru/viewart.php?id=274 Тут описываются все остальные тэги для оформления текста.
Спасибо, спешил, не подумал прочитать как надо вставлять код в топик. Извиняюсь. Кстати, компилил я эту программу в з-х ОСях - FC-5, ASP-11, и Mandriva Linux 2006. Везде у меня кодировка UTF-8.
В общем так: если исходник программы и локаль koi8-r - все выводится нормально, табличка правильная. Если исходник и локаль utf-8 - русскоязычные строчки начинают съезжать. Видимо, действительно дело в количестве байт на символ.
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #19 : 22-09-2006 14:19 » 

Всем привет! Улыбаюсь

вот этот код работает Улыбаюсь
Код:
#include <iostream>
#include <iomanip>
#include <locale>
#include <string>

#define _T(S) L##S
#define TCHAR wchar_t
#define OSTREAM wcout

TCHAR month[12][25]={_T("Январь"), _T("Февраль"), _T("March"), _T("April"),
                 _T("May"), _T("June"), _T("July"), _T("August"), _T("September"),
                    _T("November"), _T("December")};

using namespace std;

void showtable(int size) {
    OSTREAM<<setw(15)<<_T("Месяц")<<_T(" | ");
    OSTREAM<<setw(20)<<_T("Средний траффик")<<_T(" | ");
    OSTREAM<<setw(15)<<_T("В текущем году")<<_T(" | ");
    OSTREAM<<setw(10)<<_T("Разница")<<endl;
    for(int i=0; i<size; i++) {
        OSTREAM<<setw(15)<<month[i]<<_T(" | ");
        OSTREAM<<setw(20)<<i<<_T(" | ");
        OSTREAM<<setw(15)<<i<<_T(" | ");
        OSTREAM<<setw(10)<<(0)<<endl;
    }
}

int main(int argc,const char *argv[])
{
if (argc < 2) return 1;
if (strcmp(nl_langinfo(CODESET),"UTF-8"))
{
    setlocale(LC_CTYPE, "");
    OSTREAM << _T("Locale UTF-8\n");
}
locale loc(argv[1]);
showtable(3);
return 0;
}

запускал так:
./test "ru_RU.UFT-8"

man unicode
man utf-8

я в отпуске, так наврятли отвечу если будут вопросы Ага

PS: обёртка из макро определений для удобства эксперементов
Записан

Странно всё это....
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines