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

возвращаю указатель на строку пишет кракозяблы - C++

Восстановить пароль Регистрация
 
freeax
2 / 2 / 1
Регистрация: 19.09.2012
Сообщений: 135
12.04.2013, 07:16     возвращаю указатель на строку пишет кракозяблы #1
Здравствуйте!

Помогите пожалуйста с такой проблемой:

Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
const char* cModems::GetNameModem(unsigned int id) {
 
    CTAPIApp app;
    app.InitModems();
 
    printf("%s\n",app.m_modems[id].m_lineName.c_str());
 
    return app.m_modems[id].m_lineName.c_str();
}



вывожу след образом
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
int _tmain(int argc, _TCHAR* argv[]) {
    cModems modems;
 
    printf("%s\n",modems.GetNameModem(0));
 
...




на выходе получаю

Кликните здесь для просмотра всего текста

HUAWEI Mobile Connect - 3G Modem
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■


Другими словами в методе принтф печатает, то что надо, получая указатель app.m_modems[id].m_lineName.c_str(). А вот, когда указатель возвращает метод фигня получается.
Подскажите в чем проблема.
Заранее благодарен
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.04.2013, 07:16     возвращаю указатель на строку пишет кракозяблы
Посмотрите здесь:

Указатель на строку массива C++
C++ Указатель на строку
указатель на строку типа Integer C++
Указатель на строку: как выводить не всю строку целиком, а конкретную букву C++
Указатель на строку C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
solar_wind
 Аватар для solar_wind
740 / 731 / 39
Регистрация: 06.07.2009
Сообщений: 2,937
Завершенные тесты: 1
12.04.2013, 07:31     возвращаю указатель на строку пишет кракозяблы #2
CTAPIApp app у тебя создан статически в GetNameModem, после выполнения этой функции он удаляется. Так что вполне логично что у тебя выводится очищенная после удаления app память....
freeax
2 / 2 / 1
Регистрация: 19.09.2012
Сообщений: 135
12.04.2013, 08:14  [ТС]     возвращаю указатель на строку пишет кракозяблы #3
Цитата Сообщение от solar_wind Посмотреть сообщение
CTAPIApp app у тебя создан статически в GetNameModem, после выполнения этой функции он удаляется. Так что вполне логично что у тебя выводится очищенная после удаления app память....
Спасибо,
в современной практике используют объекты созданные статически или все-таки лучше работать с указателями?
solar_wind
 Аватар для solar_wind
740 / 731 / 39
Регистрация: 06.07.2009
Сообщений: 2,937
Завершенные тесты: 1
12.04.2013, 08:18     возвращаю указатель на строку пишет кракозяблы #4
freeax, Все зависит от того, что тебе нужно. Если тебе нужен объект только в одной функции то зачем его создавать динамически...его же еще удалять потом вручную придется. Так что используют и то и другое, главное использовать к месту )
freeax
2 / 2 / 1
Регистрация: 19.09.2012
Сообщений: 135
12.04.2013, 08:25  [ТС]     возвращаю указатель на строку пишет кракозяблы #5
Цитата Сообщение от solar_wind Посмотреть сообщение
freeax, Все зависит от того, что тебе нужно. Если тебе нужен объект только в одной функции то зачем его создавать динамически...его же еще удалять потом вручную придется. Так что используют и то и другое, главное использовать к месту )
Посмотрите, такой код будет к месту?)
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const char* cModems::GetNameModem(unsigned int id) {
    CTAPIApp app;
    app.InitModems();
 
    CharToOem(app.m_modems[id].m_lineName.c_str(), Name);
 
    return Name;
}
 
char* cModems::GetCOMModem(unsigned int id) {
    CTAPIApp app;
    app.InitModems();
 
    CharToOem(app.m_modems[id].GetPort().c_str(), COMPort);
    
    return COMPort;
}
solar_wind
 Аватар для solar_wind
740 / 731 / 39
Регистрация: 06.07.2009
Сообщений: 2,937
Завершенные тесты: 1
12.04.2013, 08:30     возвращаю указатель на строку пишет кракозяблы #6
freeax, Ну если у тебя Name и COMPort описаны как элементы класса, тогда тоже вариант.
Единственное класс называется cModems, по логике может отвечать за множество модемов. Вот если он отвечат за один модем, то твой подход вполне корректен, если данные переменные ты собираешься дальше использовать; а если модемов много, то не совсем правильно пихать все в одну переменную... Проще снаружи создать переменную и передать ее адрес в GetNameModem, в котором по этому адресу поместится ответ, как вариант.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
12.04.2013, 09:57     возвращаю указатель на строку пишет кракозяблы #7
Цитата Сообщение от solar_wind Посмотреть сообщение
CTAPIApp app у тебя создан статически в GetNameModem
Не статически, а автоматически. Если б статически, то такой проблемы как раз бы не было.
freeax
2 / 2 / 1
Регистрация: 19.09.2012
Сообщений: 135
15.04.2013, 11:44  [ТС]     возвращаю указатель на строку пишет кракозяблы #8
Здравствуйте!
Решил выбросить код, который определяет модемы, в длл (MSVS 2010). При вызове функции из длл в ansi c выводит кракозяблы

Кликните здесь для просмотра всего текста

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
// stdafx.h
...
typedef struct {
   char name[1024];
   char port[6];
} ModemType, *pModemType;
...
#define MYAPI extern "C" __declspec(dllexport)
...
MYAPI int GetModems(ModemType *, unsigned int *);
 
// dll3.cpp
 
...
int GetModems(ModemType *pModems, unsigned int *num) {
    CTAPIApp app;
 
    app.InitModems();
    *num = app.m_modems.size();
 
    for (unsigned int i = 0; i < *num; i++) {
        OemToCharA(app.m_modems[i].m_lineName.c_str(), pModems->name);
        OemToCharA(app.m_modems[i].GetPort().c_str(), pModems->port);
        pModems++;
    }
 
    return (*num);
}


вызов си

Кликните здесь для просмотра всего текста

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
...
ModemType modems[1024];
pModemType pModems;
...
unsigned int num;
typedef int (__cdecl* PfnGetModems)(ModemType *, unsigned int *);
 
int main (int argc, char *argv[]) {  
 
    HINSTANCE hGetProcIDDLL = LoadLibrary("dll3.dll");
    if (hGetProcIDDLL == NULL) {
        MessageBox(NULL,"Error load dll","DLL Error",MB_OK | MB_ICONERROR);
        return EXIT_FAILURE;
    }
 
    PfnGetModems myDllGetModems = (PfnGetModems)GetProcAddress(hGetProcIDDLL, "GetModems"); 
 
    if (!myDllGetModems) {
        MessageBox(NULL,"Error load GetModems()","DLL Error",MB_OK | MB_ICONERROR);     
        return EXIT_FAILURE;
    }
 
    myDllGetModems(modems, &num);
    pModems = modems;   
    printf("%s - %s\n", pModems->name, pModems->port);
 
...


Подскажите где проблема
Заранее благодарен!

Для справки, unsigned int num возвращается как надо. А вот в pModems->name и pModems->port мусор какой-то
Подскажите пожалуйста!!
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
17.04.2013, 07:26     возвращаю указатель на строку пишет кракозяблы #9
freeax, возможно проблема в OemToCharA? Не пробовали без нее, или вместо нее использовать WinAPI функцию OemToChar?
freeax
2 / 2 / 1
Регистрация: 19.09.2012
Сообщений: 135
17.04.2013, 08:03  [ТС]     возвращаю указатель на строку пишет кракозяблы #10
Цитата Сообщение от Toshkarik Посмотреть сообщение
freeax, возможно проблема в OemToCharA? Не пробовали без нее, или вместо нее использовать WinAPI функцию ?
с OemToChar
Кликните здесь для просмотра всего текста

C++
1
2
Ошибка  1   error C2664: OemToCharW: невозможно преобразовать параметр 2 из 'char [1024]' в 'LPWSTR'    d:\new2\dll\dll\dll\dll.cpp 29  dll
Ошибка  2   error C2664: OemToCharW: невозможно преобразовать параметр 2 из 'char [6]' в 'LPWSTR'   d:\new2\dll\dll\dll\dll.cpp 30  dll



делаю

Кликните здесь для просмотра всего текста

C++
1
2
OemToChar(app.m_modems[i].m_lineName.c_str(), (LPWSTR)pModems->name);
OemToChar(app.m_modems[i].GetPort().c_str(), (LPWSTR)pModems->port);



выдает

H - С!f&

а как без OemToCharA ? memcpy ?
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
17.04.2013, 08:06     возвращаю указатель на строку пишет кракозяблы #11
Цитата Сообщение от freeax Посмотреть сообщение
memcpy
Вполне сойдет простой strcpy.

Цитата Сообщение от freeax Посмотреть сообщение
error C2664: OemToCharW: невозможно преобразовать параметр 2 из
В настройках проекта отключите Unicode.
freeax
2 / 2 / 1
Регистрация: 19.09.2012
Сообщений: 135
17.04.2013, 08:51  [ТС]     возвращаю указатель на строку пишет кракозяблы #12
Цитата Сообщение от Toshkarik Посмотреть сообщение
В настройках проекта отключите Unicode.
Спасибо, все заработало
расскажите подробнее об этом, чет я не врубаюсь что изменилось
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
17.04.2013, 08:59     возвращаю указатель на строку пишет кракозяблы #13
freeax, как я понял, CharToOem это макрос, когда включен Unicode в проекте, в него подставляется функция для работы с wide-строками ( wchar_t ), при отключении Unicode, подставляется функция для простых строк ( char ).
Сейчас глянул, при выключенном Unicode вызывается та же CharToOemA().
Так что вряд ли что то изменится в работе.
Просто копировать строку пробовали?
freeax
2 / 2 / 1
Регистрация: 19.09.2012
Сообщений: 135
17.04.2013, 10:00  [ТС]     возвращаю указатель на строку пишет кракозяблы #14
Цитата Сообщение от Toshkarik Посмотреть сообщение
freeax, как я понял, CharToOem это макрос, когда включен Unicode в проекте, в него подставляется функция для работы с wide-строками ( wchar_t ), при отключении Unicode, подставляется функция для простых строк ( char ).
Сейчас глянул, при выключенном Unicode вызывается та же CharToOemA().
Так что вряд ли что то изменится в работе.
Просто копировать строку пробовали?
Да, включил Unicode

вместо
OemToChar(app.m_modems[i].m_lineName.c_str(), (LPWSTR)pModems->name);
написал
strcpy_s(pModems->name, app.m_modems[i].m_lineName.c_str());

при вызове myDllGetModems(modems, &num); в pModems->name символ "H" и больше ничего

короче говоря запутался совсем, не могу понять почему с юникодом не пашет

с memcpy(pModems->name,app.m_modems[i].m_lineName.c_str(),app.m_modems[i].m_lineName.size()); та же история (при вызове myDllGetModems(modems, &num); в pModems->name символ "H" и больше ничего)

Добавлено через 6 минут
но если в библе меняю указатель строки на константу:

C++
1
memcpy(pModems->name,"",strlen("Nothing"));
то при вызове myDllGetModems(modems, &num); в pModems->name Nothing все нормально...

видимо что-то с app.m_modems[i].m_lineName не то...
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.04.2013, 10:02     возвращаю указатель на строку пишет кракозяблы
Еще ссылки по теме:

Как описать в структуре строку не через указатель C++
C++ Работа с строкой (указатель на строку)
Вернуть указатель на строку C++

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

Или воспользуйтесь поиском по форуму:
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
17.04.2013, 10:02     возвращаю указатель на строку пишет кракозяблы #15
для печати вы используете
printf("%s - %s\n", pModems->name, pModems->port);
%s - это означает что нужно выводить сишную строки. это массив char заканчивающийся нулем.
memcpy(pModems->name,app.m_modems[i].m_lineName.c_str(),app.m_modems[i].m_lineName.size());
вот тут - копирование юникодных строк в массив чаров. юникодный символ занимает два байта, один
из которых запросто может быть нулем. и когда printf печатает строку, она натыкается на такой нулевой
байт и считает, что строка на этом закончилась. она ведь думает, что её отдали сишную, а не юникодную
строку.
выведете на печать код каждого символа из своего массива после копирования в него юникодной строки
Yandex
Объявления
17.04.2013, 10:02     возвращаю указатель на строку пишет кракозяблы
Ответ Создать тему
Опции темы

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