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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
freeax
2 / 2 / 1
Регистрация: 19.09.2012
Сообщений: 136
#1

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

12.04.2013, 07:16. Просмотров 510. Ответов 14
Метки нет (Все метки)

Здравствуйте!

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

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

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++
Скажите пожалуйста если есть string str="Big!"; string *pt=&str;, как можно обратиться к 'B' или '!' через pt, и возможно ли это...

Указатель на строку - C++
Доброго времени суток. У меня вопрос по поводу *char К примеру у меня есть функция void get(char *s1) { s1="hello"; } ...

Указатель на строку - C++
Хочу считать строку какой угодно длины, ограниченной разве памятью компа.Затем надо получить указатель на эту строку, чтоб работать, как...

Вернуть указатель на строку - C++
Найти в массиве вторую строку, содержащую хотя бы один ноль. Вернуть указатель на эту строку, вывести ее на экран.

Массив и указатель на строку - C++
class Frabjous { private: char fab; public: Frabjous(const char *s="C++"):fab(s) {} ... }

Указатель на строку массива - C++
Попалось на глаза задание: Написать функцию get_arr, которая предназначена для заполнения значениями двумерных массивов произвольной...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
solar_wind
756 / 747 / 42
Регистрация: 06.07.2009
Сообщений: 2,969
Завершенные тесты: 1
12.04.2013, 07:31     возвращаю указатель на строку пишет кракозяблы #2
CTAPIApp app у тебя создан статически в GetNameModem, после выполнения этой функции он удаляется. Так что вполне логично что у тебя выводится очищенная после удаления app память....
freeax
2 / 2 / 1
Регистрация: 19.09.2012
Сообщений: 136
12.04.2013, 08:14  [ТС]     возвращаю указатель на строку пишет кракозяблы #3
Цитата Сообщение от solar_wind Посмотреть сообщение
CTAPIApp app у тебя создан статически в GetNameModem, после выполнения этой функции он удаляется. Так что вполне логично что у тебя выводится очищенная после удаления app память....
Спасибо,
в современной практике используют объекты созданные статически или все-таки лучше работать с указателями?
solar_wind
756 / 747 / 42
Регистрация: 06.07.2009
Сообщений: 2,969
Завершенные тесты: 1
12.04.2013, 08:18     возвращаю указатель на строку пишет кракозяблы #4
freeax, Все зависит от того, что тебе нужно. Если тебе нужен объект только в одной функции то зачем его создавать динамически...его же еще удалять потом вручную придется. Так что используют и то и другое, главное использовать к месту )
freeax
2 / 2 / 1
Регистрация: 19.09.2012
Сообщений: 136
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
756 / 747 / 42
Регистрация: 06.07.2009
Сообщений: 2,969
Завершенные тесты: 1
12.04.2013, 08:30     возвращаю указатель на строку пишет кракозяблы #6
freeax, Ну если у тебя Name и COMPort описаны как элементы класса, тогда тоже вариант.
Единственное класс называется cModems, по логике может отвечать за множество модемов. Вот если он отвечат за один модем, то твой подход вполне корректен, если данные переменные ты собираешься дальше использовать; а если модемов много, то не совсем правильно пихать все в одну переменную... Проще снаружи создать переменную и передать ее адрес в GetNameModem, в котором по этому адресу поместится ответ, как вариант.
Kastaneda
Форумчанин
Эксперт С++
4514 / 2856 / 228
Регистрация: 12.12.2009
Сообщений: 7,250
Записей в блоге: 1
Завершенные тесты: 1
12.04.2013, 09:57     возвращаю указатель на строку пишет кракозяблы #7
Цитата Сообщение от solar_wind Посмотреть сообщение
CTAPIApp app у тебя создан статически в GetNameModem
Не статически, а автоматически. Если б статически, то такой проблемы как раз бы не было.
freeax
2 / 2 / 1
Регистрация: 19.09.2012
Сообщений: 136
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
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
17.04.2013, 07:26     возвращаю указатель на строку пишет кракозяблы #9
freeax, возможно проблема в OemToCharA? Не пробовали без нее, или вместо нее использовать WinAPI функцию OemToChar?
freeax
2 / 2 / 1
Регистрация: 19.09.2012
Сообщений: 136
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
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
17.04.2013, 08:06     возвращаю указатель на строку пишет кракозяблы #11
Цитата Сообщение от freeax Посмотреть сообщение
memcpy
Вполне сойдет простой strcpy.

Цитата Сообщение от freeax Посмотреть сообщение
error C2664: OemToCharW: невозможно преобразовать параметр 2 из
В настройках проекта отключите Unicode.
freeax
2 / 2 / 1
Регистрация: 19.09.2012
Сообщений: 136
17.04.2013, 08:51  [ТС]     возвращаю указатель на строку пишет кракозяблы #12
Цитата Сообщение от Toshkarik Посмотреть сообщение
В настройках проекта отключите Unicode.
Спасибо, все заработало
расскажите подробнее об этом, чет я не врубаюсь что изменилось
Toshkarik
1140 / 857 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
17.04.2013, 08:59     возвращаю указатель на строку пишет кракозяблы #13
freeax, как я понял, CharToOem это макрос, когда включен Unicode в проекте, в него подставляется функция для работы с wide-строками ( wchar_t ), при отключении Unicode, подставляется функция для простых строк ( char ).
Сейчас глянул, при выключенном Unicode вызывается та же CharToOemA().
Так что вряд ли что то изменится в работе.
Просто копировать строку пробовали?
freeax
2 / 2 / 1
Регистрация: 19.09.2012
Сообщений: 136
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     возвращаю указатель на строку пишет кракозяблы
Еще ссылки по теме:

указатель на строку типа Integer - C++
Необходимо в тэг компонента записать указатель на строку. Можно ли задать указатель на строку типа Integer напрямую? я делал так ...

Работа с строкой (указатель на строку) - C++
Написал такую программку которая будет в будущем подсчитывать количество продуктов, цены на отдельные продукты и цены общие.. с самого...

Строковый литерал и указатель на строку. В чем разница? - C++
Добрый день. Начал только изучать С++, не могу понять в чем разница между указателем на литерал и указателем на строку??? Заранее...

Как описать в структуре строку не через указатель - C++
Есть структура struct InfoBuf { size_t Len; char Data; / ??? static InfoBufType* Create(size_t Size, char* Val){ InfoBufType*...


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

Или воспользуйтесь поиском по форуму:
DU
1482 / 1058 / 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     возвращаю указатель на строку пишет кракозяблы
Ответ Создать тему
Опции темы

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