Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Не присваивается значение элементу массива LPWSTR

37K
24 июня 2011 года
Tolias28
48 / / 20.09.2010
Есть кусок кода некоторой программы на C++
 
Код:
LPWSTR dir;
    GetModuleFileName(NULL, dir, 300);
    //dir[3]='!';
    int i, j=0;
    for(i=0;dir!='\0';i++)
        if(dir=='\\')
            j=i;
    dir[j]='\0';
    j++;


Пишу в Visual Studio 2010.
Вопрос такой: Почему строка [COLOR="#800080"]dir[j]='\0';[/COLOR] игнорируется и не выполняется как будто в коде ее вообще нет?
Вот поставил я брекпоинты на всех строках этого кода, запустил, и брекпоинт со строки "[COLOR="#800080"]dir[j]='\0';[/COLOR]" исчезает! И когда программа выполняется, то эту строку вообще пропускает, как будто там ничего нет.

В коде, что я привел выше, вы видите третью строку закоментированной. Если ее раскоментировать, то эта строчка выполнится без проблем. Но как только ее поместить ниже цикла, так тут же она игнорируется! :confused:
Я вообще не въежаю, как объяснить такое странное поведение?? Объясните пожалуйста, а то у меня от этого странного поведения уже мозг кипит.


P.S. Сама задача этого кода в следующем: получить полный путь к текущей программе и отбросить в пути имя программы, оставив таким образом только путь к папке программы.
33K
24 июня 2011 года
hivewarrior
205 / / 16.11.2010
 
Код:
LPWSTR dir
как бы намекает на юникод строку. Чую, в этом весь цымес.
278
24 июня 2011 года
Alexander92
1.1K / / 04.08.2008
Во-первых, у тебя алгоритмически неправильно задача решена.
[QUOTE=Tolias28]
Сама задача этого кода в следующем: получить полный путь к текущей программе и отбросить в пути имя программы, оставив таким образом только путь к папке программы.
[/QUOTE]
Ты отрежешь таким кодом букву диска, а не полный путь. Читать строку с конца нужно для того, чтобы сделать то, что ты хочешь. А правильный код выглядит следующим образом:
Код:
#include <stdio.h>
#include <windows.h>

int main(void) {
    wchar_t dir[MAX_PATH] = {0};
    GetModuleFileName(GetModuleHandle(NULL), dir, MAX_PATH);
    int i = 0;
    for (i = lstrlen(dir); i >= 0; i--) {
        if (dir == L'\\') {
            dir = L'\0';
            break;
        }
    }
    i++;
    wprintf(L"%s\n", dir);
    return 0;
}

Обрати внимание, что я убрал переменную j, она там просто лишняя.
33K
24 июня 2011 года
hivewarrior
205 / / 16.11.2010
Алгоритмически было решено вполне правильно.
Там, цикл запоминает '\\' каждый раз, но цикл не заканчивается после этого. А закончится, когда встретится с '\0'. Таким образом, когда цикл закончится, в переменной j будет торчать номер последний '\\'.

-------------------------------------------------------------------------------------------
UPD
На самом деле тот вариант, может, быть и быстрее. Там нет lstrlen, которая сделает один проход по массиву, чтобы узнать его длину, но с другой стороны, при длинных именах и директориях будет быстрее ваш вариант, так как в lstrlen нет лишней проверки. Так что бросаться про алгоритмически неверно не стоит сразу.
33K
24 июня 2011 года
hivewarrior
205 / / 16.11.2010
У меня, кстати, заработал код, который автор привел на компиляторе от Борланда. Не думал, что они сильно отличаются от микрософтовавского, но нет, правда оказалось жестокой.
240
24 июня 2011 года
aks
2.5K / / 14.07.2006
Автор начни с того, что ты не выделяешь память под dir и в итоге все время пишешь по какому то случайному указателю. После такого можешь ждать от программы чего угодно не удивляясь. =)
33K
24 июня 2011 года
hivewarrior
205 / / 16.11.2010
Цитата: aks
Автор начни с того, что ты не выделяешь память под dir и в итоге все время пишешь по какому то случайному указателю. После такого можешь ждать от программы чего угодно не удивляясь. =)



Кстати, да. Я что-то не заметил этот косяк, а проверял константой. Пичаль мне.:facepalm:

278
24 июня 2011 года
Alexander92
1.1K / / 04.08.2008
Цитата: hivewarrior
Алгоритмически было решено вполне правильно.
Там, цикл запоминает '\\' каждый раз, но цикл не заканчивается после этого. А закончится, когда встретится с '\0'. Таким образом, когда цикл закончится, в переменной j будет торчать номер последний '\\'.

-------------------------------------------------------------------------------------------
UPD
На самом деле тот вариант, может, быть и быстрее. Там нет lstrlen, которая сделает один проход по массиву, чтобы узнать его длину, но с другой стороны, при длинных именах и директориях будет быстрее ваш вариант, так как в lstrlen нет лишней проверки. Так что бросаться про алгоритмически неверно не стоит сразу.



Виноват, не заметил. Принято.

37K
24 июня 2011 года
Tolias28
48 / / 20.09.2010
Цитата: hivewarrior
Алгоритмически было решено вполне правильно.
Там, цикл запоминает '\\' каждый раз, но цикл не заканчивается после этого. А закончится, когда встретится с '\0'. Таким образом, когда цикл закончится, в переменной j будет торчать номер последний '\\'.

-------------------------------------------------------------------------------------------
UPD
На самом деле тот вариант, может, быть и быстрее. Там нет lstrlen, которая сделает один проход по массиву, чтобы узнать его длину, но с другой стороны, при длинных именах и директориях будет быстрее ваш вариант, так как в lstrlen нет лишней проверки. Так что бросаться про алгоритмически неверно не стоит сразу.


Спасибо за разъяснение) Я уже хотел это самое писать, как увидел, что вы ниже это уже сделали за меня)
Да да, именно потому я вырешил не использовать strlen, а узнавать последний слеш за один проход в цикле.

Спасибо за пример, в котором цикл идет от последнего символа. Работает. Но я все же хотел склониться к своему решению, в котором не используется strlen...

Цитата:
Автор начни с того, что ты не выделяешь память под dir и в итоге все время пишешь по какому то случайному указателю. После такого можешь ждать от программы чего угодно не удивляясь. =)


Каюсь... Признаюсь, я в самом начале память под dir выделял, но тогда компилятор ругался на невозможность преобразования:

Цитата:
IntelliSense: argument of type "LPWSTR *" is incompatible with parameter of type "LPWSTR"


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

Upd:
Выделил память под dir, но строка dir[j]='\0'; всеравно не исполняется(( Почему?

33K
24 июня 2011 года
hivewarrior
205 / / 16.11.2010
wchar_t* dir=new wchar_t [MAX_PATH] нэ?
37K
24 июня 2011 года
Tolias28
48 / / 20.09.2010
не:) А какая в даном случае разница, объявлять массив статически или динамически:) Проблема оказалась не в этом. Как мне подсказали на другом форуме, трабл заключался в том, что я все эти отладки и правки кода делал в релиз, а не в дебаг! Элементарно то как... Никогда не думал, что при отладке в релизе могут быть такие приколы. Теперь буду знать. Проблема решена и мой вопрос полностью исчерпан.
7
24 июня 2011 года
@pixo $oft
3.4K / / 20.09.2006
aks
Вот и я это заметил и думаю,что-то тут не так:)

ТС:
Для означенной задачи есть более удобная функция,которая по пути получает и имя папки отдельно,и имя программы[COLOR="#c0c0c0"],и блэкджек со шлюхами…[/COLOR]
260
24 июня 2011 года
Ramon
1.1K / / 16.08.2003
Цитата: @pixo $oft
aks
Вот и я это заметил и думаю,что-то тут не так:)

ТС:
Для означенной задачи есть более удобная функция,которая по пути получает и имя папки отдельно,и имя программы[COLOR="#c0c0c0"],и блэкджек со шлюхами…[/COLOR]



Не разрушай этот мир велосипедов.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог