Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > LPTSTR и strcat()


Автор: Madest 27.5.2004, 19:25
Код
CString sq;
LPTSTR lp=new char[80];

lp="c:\\";
sq.Format("1- %s",lp);
AfxMessageBox(sq);

lp="c:\\ZEZO\\p";
sq.Format("2- %s",lp);
AfxMessageBox(sq);

strcat(lp,"1");
sq.Format("3- %s",lp);
AfxMessageBox(sq);

Когда программа первый раз исполняет этот код, выдается:
    1- с:\
    2- c:\ZEZO\p
    3- c:\ZEZO\p1
Если не выходя из программы обратиться к этому коду еще раз, то выдает:
    1- с:\
    2- c:\ZEZO\p1
    3- c:\ZEZO\p11
Почему, когда я в части 2 присваиваю lp="c:\\ZEZO\\p"; lp получается с единичкой на конце?! Ведь присваивается нормально ей в части 1 "c:\\". Догадываюсь, что виной тому strcat(). А чего же делать?

Автор: kruchinin 27.5.2004, 19:41
strcat здесь не причем (и вообще есть APi-шные функции для работы в Windows - lstrcat)
попробуй не присваивать
Код

lp="c:\\ZEZO\\p";

а везде делать
Код

lstrcpy(lp,"c:\\ZEZO\\p");

или strcpy - просто зачем подключать еще одну библиотеку если при работе с Win приложением у тебя автоматически есть та функция

Автор: Madest 27.5.2004, 19:56
Если так:
Код
lstrcpy(lp,"c:\\ZEZO\\p");
strcat(lp,"1");

то тогда при передаче lp в
Код
SHFILEOPSTRUCT sh;
...
sh.pFrom=lp;
...
SHFileOperation(&sh);

это не работает =(

Автор: Baa 27.5.2004, 22:36
Только так smile.gif При твоем варианте ты вообще не понятно зачем выделяешь память.
Видимо не совсем понимаешь, что есть указатель.
Ты сначала зарезервировал 80 байт.
На них указывает твой указатель, а потом ты взял и поменял ему место, на которое он указывает, на адрес, где записан твой "c:\\"
соотв. дальше ты делаешь примерно тоже самое, а в конце вообще кульминация.
Ты дописываешь 1 в память, где была записана та константа, затирая то, что после неё.
Код

CString sq;
LPTSTR lp = new TCHAR [80];

lstrcpy (lp, "c:\\");
sq.Format("1- %s",lp);
AfxMessageBox(sq);

lstrcpy(lp, "c:\\ZEZO\\p");
sq.Format("2- %s",lp);
AfxMessageBox(sq);

lstrcat(lp,"1");
sq.Format("3- %s",lp);
AfxMessageBox(sq);
delete [] lp;

Автор: Madest 28.5.2004, 00:31
Эти мои изыскания от безысходности =)
Этот фрагмент, вообще, лишь для того, чтоб убедиться сам не знаю в чем:
Код
lp="c:\\";
sq.Format("1- %s",lp);
AfxMessageBox(sq);

В общем, цель удалить директорию с файлами. Взял из FAQ:
Код
SHFILEOPSTRUCT sh;
sh.hwnd=pFrame->m_hWnd;
sh.wFunc=FO_DELETE;
sh.pFrom="/*некий путь*/";
sh.pTo="NULL";
sh.fFlags=FOF_NOCONFIRMATION|FOF_SILENT;
sh.hNameMappings=0;
sh.lpszProgressTitle=NULL;
SHFileOperation(&sh);

А мне путь заранее неизвестен. Вот и пытаюсь:
Код
LPTSTR lp;
lp="c:\\ZEZO\\p";
strcat(lp,"допустим 1");

Так срабатывает, но только один раз.
А так ни разу:
Код
LPTSTR lp;
lstrcpy(lp,"c:\\ZEZO\\p");
lstrcat(lp,"1");

Пишет: "Не удается удалить файл. Не удается произвести чтение из файла или с диска."
Что же делать?!

Автор: AndyY 28.5.2004, 01:23
нужно так:
char sz[MAX_PATH];
strcpy( sz, "c:\\zero\\" );
strcat( sz, 1 );

ну или через new, malloc распределить память.

а то ты пытаешься менять область памяти со статическими данными.

а вообще хороший стиль - пользоваться функциями _tcs* (например, _tcscpy)
еще лучше - с проверкой длинны строк (_tcsncpy)

Автор: Madest 28.5.2004, 01:39
Как все просто =) Перемудрил =)
Спасибо!

Автор: Shootnik 1.10.2008, 01:38
Код

            char sz[100];
            strcpy( sz, "\\Temp\\Пробник\0" );//strcpy( sz, nameOfDirectory );
            SHFILEOPSTRUCT sh;
            sh.hwnd   = GetSafeHwnd(); 
            sh.wFunc  = FO_DELETE;
            sh.pFrom  = sz;
            sh.pTo    = NULL;
            sh.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
            sh.hNameMappings = 0;
            sh.lpszProgressTitle = NULL;
            SHFileOperation (&sh);

Выдает такую же ошибку, как и у Madest'а. nameOfDirectory - имя папки, которую нужно удалить. Насколько я понял, здесь что-то с преобразованием char* в const char*. Но как это исправить. Буду очень благодарен, если напишите конкретный пример, так как моих знаний на понятия общих объяснений может не хватить. Заранее спасибо.

Автор: J0ker 1.10.2008, 03:16
Цитата(Shootnik @  1.10.2008,  01:38 Найти цитируемый пост)
strcpy( sz, "\\Temp\\Пробник\0" );


чо это за \0 у вас?

Автор: Shootnik 1.10.2008, 10:22
Цитата(J0ker @  1.10.2008,  03:16 Найти цитируемый пост)
чо это за \0 у вас? 

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

Автор: J0ker 1.10.2008, 15:36
Цитата(Shootnik @ 1.10.2008,  10:22)
Цитата(J0ker @  1.10.2008,  03:16 Найти цитируемый пост)
чо это за \0 у вас? 

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

я просто подумал возможно вы хотели написать "\\Temp\\Пробник\\0" и "0" - часть имени...

Автор: xvr 1.10.2008, 17:07
Цитата(Shootnik @ 1.10.2008,  01:38)
Код

            char sz[100];
            strcpy( sz, "\\Temp\\Пробник\0" );//strcpy( sz, nameOfDirectory );
            SHFILEOPSTRUCT sh;
            sh.hwnd   = GetSafeHwnd(); 
            sh.wFunc  = FO_DELETE;
            sh.pFrom  = sz;
            sh.pTo    = NULL;
            sh.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
            sh.hNameMappings = 0;
            sh.lpszProgressTitle = NULL;
            SHFileOperation (&sh);

Выдает такую же ошибку, как и у Madest'а. nameOfDirectory - имя папки, которую нужно удалить. Насколько я понял, здесь что-то с преобразованием char* в const char*. Но как это исправить. Буду очень благодарен, если напишите конкретный пример, так как моих знаний на понятия общих объяснений может не хватить. Заранее спасибо.

Цитата

pFrom
Address of a buffer to specify one or more source file names. These names must be fully qualified paths. Standard Microsoft® MS-DOS® wild cards, such as "*", are permitted in the file-name position. Although this member is declared as a null-terminated string, it is used as a buffer to hold multiple file names. Each file name must be terminated by a single NULL character. An additional NULL character must be appended to the end of the final name to indicate the end of pFrom.
Судя по \0 в strcpy( sz, "\\Temp\\Пробник\0" ) такое намеренье было, но вся проблема в том, что strcpy не скопирует лишний 0  smile Так что напиши просто
Код

sh.pFrom  = "\\Temp\\Пробник\0";


Автор: Shootnik 1.10.2008, 18:48
Если писать так
Код

            SHFILEOPSTRUCT sh;
            sh.hwnd   = GetSafeHwnd(); 
            sh.wFunc  = FO_DELETE;
            sh.pFrom  =" \\Temp\\Пробник";
            sh.pTo    = NULL;
            sh.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
            sh.hNameMappings = 0;
            sh.lpszProgressTitle = NULL;
            SHFileOperation (&sh);

то все работает, но если имя папки, которую нужно удалить не фиксировано, т.е.
Код

            char sz[100];
            strcpy( sz, "\\Temp\\Пробник" );
            SHFILEOPSTRUCT sh;
            sh.hwnd   = GetSafeHwnd(); 
            sh.wFunc  = FO_DELETE;
            sh.pFrom  = sz;
            sh.pTo    = NULL;
            sh.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
            sh.hNameMappings = 0;
            sh.lpszProgressTitle = NULL;
            SHFileOperation (&sh);

то выдается ошибка.

Автор: J0ker 1.10.2008, 19:21
Цитата(Shootnik @  1.10.2008,  18:48 Найти цитируемый пост)
то выдается ошибка. 

Код

pFrom
Note  This string must be double-null terminated.

(уродство какое-то  smile )
Код

char sz[100];
memcpy( sz, "\\Temp\\Пробник\0", strlen("\\Temp\\Пробник")+2 );


Автор: Shootnik 1.10.2008, 19:38
Код

                        char sz[100];
                        memcpy( sz, "\\Temp\\Пробник\0", strlen("\\Temp\\Пробник")+2 );
            SHFILEOPSTRUCT sh;
            sh.hwnd   = GetSafeHwnd(); 
            sh.wFunc  = FO_DELETE;
            sh.pFrom  = sz;
            sh.pTo    = NULL;
            sh.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
            sh.hNameMappings = 0;
            sh.lpszProgressTitle = NULL;
            SHFileOperation (&sh);

и...
ошибка то осталась, тем более если заменить "\\Temp\\Пробник\0" на какую-нибудь другую строку

Автор: J0ker 1.10.2008, 19:54
Цитата(Shootnik @  1.10.2008,  19:38 Найти цитируемый пост)
и...
ошибка то осталась, тем более если заменить "\\Temp\\Пробник\0" на какую-нибудь другую строку 

у меня работает
какой компайлер?
проверь работает-ли на именах в латинице

и номер ошибки давай

Автор: Shootnik 1.10.2008, 21:28
Цитата(J0ker @  1.10.2008,  19:54 Найти цитируемый пост)
у меня работает
какой компайлер?

Visual c++ 6.0

Цитата(J0ker @  1.10.2008,  19:54 Найти цитируемый пост)
проверь работает-ли на именах в латинице

тоже не работает


Цитата(J0ker @  1.10.2008,  19:54 Найти цитируемый пост)
и номер ошибки давай

А где ее взять? Прога выполняется, вот только файл не удаляется: выскакивает ошибка: "Ошибка при удалении файла или папки" с текстом сообщения "Не удается удалить файл. Не удается произвести чтение из файла или с диска.".

Автор: J0ker 1.10.2008, 21:56
Цитата(Shootnik @  1.10.2008,  21:28 Найти цитируемый пост)
А где ее взять? Прога выполняется, вот только файл не удаляется: выскакивает ошибка: "Ошибка при удалении файла или папки" с текстом сообщения "Не удается удалить файл. Не удается произвести чтение из файла или с диска.". 

SHFileOperation (&sh) возвращает int - это код ошибки

Автор: Shootnik 1.10.2008, 22:40
Код

int iterator;
...
iterator=SHFileOperation (&sh);

1026

Автор: J0ker 1.10.2008, 23:54
если проект небольшой - перешлите мне я посмотрю
мыло в личку кину

Автор: xvr 2.10.2008, 08:23
Цитата(J0ker @ 1.10.2008,  21:56)
Цитата(Shootnik @  1.10.2008,  21:28 Найти цитируемый пост)
А где ее взять? Прога выполняется, вот только файл не удаляется: выскакивает ошибка: "Ошибка при удалении файла или папки" с текстом сообщения "Не удается удалить файл. Не удается произвести чтение из файла или с диска.". 

SHFileOperation (&sh) возвращает int - это код ошибки

SHFileOperation возвращает признак ошибки (0 или не 0), а код ошибки возвращает GetLastError(), которую надо позвать после этого.

Shootnik - что возвращает GetLastError() ?

Автор: Dov 2.10.2008, 08:53
Цитата(Shootnik @  1.10.2008,  18:48 Найти цитируемый пост)
но если имя папки, которую нужно удалить не фиксировано, то выдается ошибка.

Shootnik, попробуй так:
Код
sh.pFrom  = (LPCTSTR)sz;

Автор: Madest 2.10.2008, 10:15
Shootnik, попробуй в пути вместо "\\" - "/" использовать. Чего получится? 
Эх, какие вопросы 4 года назад были. А разъяснение уважаемого Baa я тогда так и не понял, списал на чудеса. В указателях тогда уже разбирался, но со строками у меня взаимная неприязнь была =)

Автор: xvr 2.10.2008, 10:45
Уже пошли советы из области плясок с бубном  smile 
 smile Анекдот:
В колхоз назначили нового председателя (который совершенно не разбирался в животноводстве и пр)
Колхоз занимается разведением кур (среди всего прочего). К председателю приходят с проблемой - куры мрут, что делать? Он дает распоряжение:
- Перенести курятник на 200 метров вправо.
- Сделано, все равно мрут
- Тогда поднять в курятнике насесты на 23 см.
- Сделано, падеж кур продолжается
- Прорубить 2 дополнительных окна
- Прорубили, куры продолжают дохнуть
- Расширить входную дверь на 15.5 см
- Расширили, все куры передохли.
- Жаль, а у меня было еще столько свежих идей  smile 

Автор: Shootnik 2.10.2008, 13:19
Цитата(Dov @  2.10.2008,  08:53 Найти цитируемый пост)
Shootnik, попробуй так:
Выделить всёкод C++
1:
    
sh.pFrom  = (LPCTSTR)sz;

не помомгло

Цитата(xvr @  2.10.2008,  08:23 Найти цитируемый пост)
2 Shootnik - что возвращает GetLastError() ? 

Код

            ...
                        SHFILEOPSTRUCT sh;
            sh.hwnd   = GetSafeHwnd(); 
            sh.wFunc  = FO_DELETE;
            sh.pFrom  = sz;
            sh.pTo    = NULL;
            sh.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
            sh.hNameMappings = 0;
            sh.lpszProgressTitle = NULL;
            SHFileOperation (&sh);
            i=GetLastError();

i = 0;
Цитата(Madest @  2.10.2008,  10:15 Найти цитируемый пост)
Shootnik, попробуй в пути вместо "\\" - "/" использовать. Чего получится? 

И опять же... та же ошибка

Автор: J0ker 2.10.2008, 16:40
Цитата(xvr @  2.10.2008,  08:23 Найти цитируемый пост)
SHFileOperation возвращает признак ошибки (0 или не 0), а код ошибки возвращает GetLastError(), которую надо позвать после этого.

2 Shootnik - что возвращает GetLastError() ? 

 smile 
SHFileOperation возвращает код ошибки
RTFM

Добавлено через 4 минуты и 6 секунд
Цитата(Shootnik @ 2.10.2008,  13:19)
Цитата(Dov @  2.10.2008,  08:53 Найти цитируемый пост)
Shootnik, попробуй так:
Выделить всёкод C++
1:
    
sh.pFrom  = (LPCTSTR)sz;

не помомгло

Цитата(xvr @  2.10.2008,  08:23 Найти цитируемый пост)
2 Shootnik - что возвращает GetLastError() ? 

Код

            ...
                        SHFILEOPSTRUCT sh;
            sh.hwnd   = GetSafeHwnd(); 
            sh.wFunc  = FO_DELETE;
            sh.pFrom  = sz;
            sh.pTo    = NULL;
            sh.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
            sh.hNameMappings = 0;
            sh.lpszProgressTitle = NULL;
            SHFileOperation (&sh);
            i=GetLastError();

i = 0;
Цитата(Madest @  2.10.2008,  10:15 Найти цитируемый пост)
Shootnik, попробуй в пути вместо "\\" - "/" использовать. Чего получится? 

И опять же... та же ошибка

давай проще сделаем - я те пришлю консольный проект который работает у меня с eeшником на тестирование
если работает - копипастишь сее функцию и приверяешь.
только мне щас надо отойти - вернусь вечером только

Автор: xvr 2.10.2008, 16:51
Цитата(J0ker @ 2.10.2008,  16:40)
Цитата(xvr @  2.10.2008,  08:23 Найти цитируемый пост)
SHFileOperation возвращает признак ошибки (0 или не 0), а код ошибки возвращает GetLastError(), которую надо позвать после этого.

2 Shootnik - что возвращает GetLastError() ? 

 smile 
SHFileOperation возвращает код ошибки
RTFM

Добавлено @ 16:44
Цитата(Shootnik @ 2.10.2008,  13:19)
Цитата(Dov @  2.10.2008,  08:53 Найти цитируемый пост)
Shootnik, попробуй так:
Выделить всёкод C++
1:
    
sh.pFrom  = (LPCTSTR)sz;

не помомгло

Цитата(xvr @  2.10.2008,  08:23 Найти цитируемый пост)
2 Shootnik - что возвращает GetLastError() ? 

Код

            ...
                        SHFILEOPSTRUCT sh;
            sh.hwnd   = GetSafeHwnd(); 
            sh.wFunc  = FO_DELETE;
            sh.pFrom  = sz;
            sh.pTo    = NULL;
            sh.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
            sh.hNameMappings = 0;
            sh.lpszProgressTitle = NULL;
            SHFileOperation (&sh);
            i=GetLastError();

i = 0;
Цитата(Madest @  2.10.2008,  10:15 Найти цитируемый пост)
Shootnik, попробуй в пути вместо "\\" - "/" использовать. Чего получится? 

И опять же... та же ошибка

давай проще сделаем - я те пришлю консольный проект который работает у меня с eeшником на тестирование
если работает - копипастишь сее функцию и приверяешь.
только мне щас надо отойти - вернусь вечером только

Хм, отчасти  smile 

Цитата

Return Value

Returns zero if successful; otherwise nonzero. Applications normally should simply check for zero or nonzero.

Do not use GetLastError with the return values of this function.

To examine the nonzero values for troubleshooting purposes, they largely map to those defined in Winerror.h. However, several of its possible return values are based on pre-Win32 error codes, which in some cases overlap the later Winerror.h values without matching their meaning. 


Ошибка 1026 соответствует
Цитата

An unknown error occurred. This is typically due to an invalid path in the source or destination.

Автор: J0ker 3.10.2008, 00:11
Цитата(xvr @  2.10.2008,  10:45 Найти цитируемый пост)
Уже пошли советы из области плясок с бубном 
 Анекдот:

это адаптированная для обывателя версия
в оригинале было про службу техподдержки, нереботающий модем и строки инициализации

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)