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

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

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

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

12.04.2013, 07:16. Просмотров 514. Ответов 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(). А вот, когда указатель возвращает метод фигня получается.
Подскажите в чем проблема.
Заранее благодарен
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.04.2013, 07:16
Здравствуйте! Я подобрал для вас темы с ответами на вопрос возвращаю указатель на строку пишет кракозяблы (C++):

Указатель на строку: как выводить не всю строку целиком, а конкретную букву - C++
Есть программка: #include<iostream> using namespace std; void fn_str1(int i,string str1,char *p) { p=&str1; ...

Разработать и испытать функцию, которая переворачивает строку и возвращает указатель на перевёрнутую строку - C++
Разработать и испытать функцию, которая переворачивает строку и возвращает указатель на перевёрнутую строку. Прототип функции инверсии...

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

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

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

Как получить ссылку на указатель или указатель на указатель в массиве? - C++
В процессе реализации сортировки пузырьком натолкнулся на такую проблему: как поменять значения указателей, передаваемых в функцию. Если...

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

Цитата Сообщение от freeax Посмотреть сообщение
error C2664: OemToCharW: невозможно преобразовать параметр 2 из
В настройках проекта отключите Unicode.
1
freeax
2 / 2 / 1
Регистрация: 19.09.2012
Сообщений: 136
17.04.2013, 08:51  [ТС] #12
Цитата Сообщение от Toshkarik Посмотреть сообщение
В настройках проекта отключите Unicode.
Спасибо, все заработало
расскажите подробнее об этом, чет я не врубаюсь что изменилось
0
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
17.04.2013, 08:59 #13
freeax, как я понял, CharToOem это макрос, когда включен Unicode в проекте, в него подставляется функция для работы с wide-строками ( wchar_t ), при отключении Unicode, подставляется функция для простых строк ( char ).
Сейчас глянул, при выключенном Unicode вызывается та же CharToOemA().
Так что вряд ли что то изменится в работе.
Просто копировать строку пробовали?
1
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 не то...
0
DU
1483 / 1129 / 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 печатает строку, она натыкается на такой нулевой
байт и считает, что строка на этом закончилась. она ведь думает, что её отдали сишную, а не юникодную
строку.
выведете на печать код каждого символа из своего массива после копирования в него юникодной строки
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.04.2013, 10:02
Привет! Вот еще темы с ответами:

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
17.04.2013, 10:02
Ответ Создать тему
Опции темы

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