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
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #1 : 11-09-2006 12:27 » |
|
А может дело, банально, в шрифте ?
|
|
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
ruddystepa
Гость
|
|
« Ответ #2 : 11-09-2006 13:07 » |
|
А может дело, банально, в шрифте ?
Не понял, причем здесь шрифт? Ведь манипулятор setw() определяет ширину поля для выводимого выражения. Если строка не влезает в это поле, выводится та часть строки, которая влезет. Во всяком случае так написано в книжках, которые я читал.
|
|
|
Записан
|
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #3 : 11-09-2006 13:50 » |
|
как ты определяешь, что "все сторочки таблицы съехали относительно друг друга"? визуально?
|
|
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
andrystepa
Помогающий
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
Спокойный
Администратор
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
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #6 : 11-09-2006 17:43 » |
|
Это мои предположения, поэтому могу и ошибаться. В Линуксе используется кодировка UTF-8. Нижняя часть (символы от 0 и до 127) ASCII таблици полностью повторяются в данной кодировке. На каждый символ отводится 1 байт. Поэтому проблем нет с работой латинского шрифта. Если самый верхний бит поднят. То на символ отводится уже два байта. Русский текст в Линуксе идет по два байта на каждый символ. Тут стандартная функция библиотеки сталкивается с проблемой подсчета количества символов. Поэтому она вообше никак не считает.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #7 : 11-09-2006 18:18 » |
|
Finch, хм. Я бы не утверждал так. Используемая кодировка определяется локалью. Ф-ии стандартной библиотеки должны ратотать согласно локали и utf8 тут не может испортить. Конечно, если используется смесь сильно разных библиотек (с поддержкой utf и без), то возможен любой эффект.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Finch
Спокойный
Администратор
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
Технический
Администратор
Offline
Пол:
|
|
« Ответ #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
Спокойный
Администратор
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
Технический
Администратор
Offline
Пол:
|
|
« Ответ #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
Спокойный
Администратор
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
Технический
Администратор
Offline
Пол:
|
|
« Ответ #13 : 11-09-2006 19:25 » |
|
Finch, учитывая, что число "проглоченных" пробелов равно числу кириллических символов - логично это связать. У тебя какая локаль, какая ОС?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Finch
Спокойный
Администратор
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
Спокойный
Администратор
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)
|
|
« Ответ #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: обёртка из макро определений для удобства эксперементов
|
|
|
Записан
|
Странно всё это....
|
|
|
|