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

Не могу разбить строку по разделителю - C++

Восстановить пароль Регистрация
 
 
nwpepper
0 / 0 / 0
Регистрация: 01.08.2016
Сообщений: 7
01.08.2016, 09:48     Не могу разбить строку по разделителю #1
Суть такая: Делаю задачу копирования информации в папку на всех устройствах.
Есть строка пути в виде: Откуда|Куда;Откуда|Куда;... и.т.д.
Не могу распарсить на токены. Я путаюсь с char, wchar, TCHAR, WCHAR, и прочими. Приходится делать много преобразований.
Вот код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
WCHAR* strForCopyFiles = getstrForCopyFiles(L"D:\\ANT\\Act_2016_07.rar", massID);   
 
    // 2. Разбираем строку и копируем файлы на устройства
    wchar_t * context = NULL;
    wchar_t * token = NULL; 
    token = wcstok_s(strForCopyFiles, L";", &context);
 
    // Всё норм, в консоль ерунду выводит
    while (token != NULL) {
            wprintf_s(L"%s\n", token);
            token = wcstok_s(NULL, L";", &context);
    }
Строка полученная: "D:\\ANT\\Act_2016_07.rar|F:\\Test; D:\\ANT\\Act_2016_07.rar|E:\\Test;"
Нужно распарсить и скопировать одно и то же значение в обе папки Test.
Проблема в том, что wprinf не выводит в консоль пути какие нужно. Все примеры сделаны в интернете с cstok_s, но у меня тип строки Unicode. Подскажите куда копать или что я не так делаю.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.08.2016, 09:48     Не могу разбить строку по разделителю
Посмотрите здесь:

Разбить строку C++
C++ Разбить строку на слова
Разбить строку C++
C++ Разбить строку
как разбить строку C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
nonedark2008
624 / 502 / 92
Регистрация: 28.07.2012
Сообщений: 1,343
01.08.2016, 10:14     Не могу разбить строку по разделителю #2
nwpepper, я ни за что не отвечаю, но верю, что вместо "%s" в wprintf нужно использовать "%ls".
nwpepper
0 / 0 / 0
Регистрация: 01.08.2016
Сообщений: 7
01.08.2016, 11:27  [ТС]     Не могу разбить строку по разделителю #3
Спасибо, поставил. Но не помогло.
Может по скриншотам кто поможет разобраться.
Миниатюры
Не могу разбить строку по разделителю   Не могу разбить строку по разделителю   Не могу разбить строку по разделителю  

Не могу разбить строку по разделителю  
nmcf
4303 / 3724 / 1255
Регистрация: 14.04.2014
Сообщений: 14,580
01.08.2016, 12:15     Не могу разбить строку по разделителю #4
С wcout работает? И какой указатель возвращает getstrForCopyFiles()? Память динамически выделяется или там какой-то буфер выше есть?
DemolitionMan
 Аватар для DemolitionMan
22 / 54 / 18
Регистрация: 06.04.2016
Сообщений: 325
01.08.2016, 12:27     Не могу разбить строку по разделителю #5
C++Builder6.
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//---------------------------------------------------------------------------
#include <vcl.h>
#include <conio.h>
#include <stdio.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
char *O, *s1, *s2, *s3, *s4;
 
char *str = "D:\\ANT\\Act_2016_07.rar|F:\\Test; D:\\ANT\\Act_2016_07.rar|E:\\Test;";
printf("Stroka=%s\n", str);
printf("sizeof(str)=%i\n", sizeof(str));
 
//--1--
//char *strtok(char *s1, const char *s2);
s1 = strtok(str, "|");
printf("s1=%s\n", s1);
//Áåðåì îñòГ*òîê.
O = strtok(NULL, ",");
if(O) printf("O=%s\n", O);
 
//--2--
s2 = strtok(O, ";");
printf("s2=%s\n", s2);
//Áåðåì îñòГ*òîê.
O = strtok(NULL, ",");
if(O) printf("O=%s\n", O);
 
//--3--
O++;
s3 = strtok(O, "|");
printf("s3=%s\n", s3);
//Áåðåì îñòГ*òîê.
O = strtok(NULL, ",");
if(O) printf("O=%s\n", O);
 
//--4--
s4 = strtok(O, ";");
printf("s4=%s\n", s4);
 
getch();
return 0;
}
nwpepper
0 / 0 / 0
Регистрация: 01.08.2016
Сообщений: 7
01.08.2016, 12:38  [ТС]     Не могу разбить строку по разделителю #6
с wcout просто черное окно консоли выдает.
Строка получается таким кодом:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
WCHAR* getstrForCopyFiles(WCHAR* myStr, std::vector<std::string> &massID)
{
    WCHAR strForCopyFiles[MAX_PATH+1] = L"";
 
    for (std::vector<std::string>::iterator it = massID.begin(); it != massID.end(); it++)
    {   
        std::wstring stemp = s2ws(*it);
        LPCWSTR result = stemp.c_str();
        lstrcat(strForCopyFiles, result);
        lstrcat(strForCopyFiles, L"|");
        lstrcat(strForCopyFiles, myStr);
        lstrcat(strForCopyFiles, L";");
    }
 
    return strForCopyFiles;
}
где s2ws(*it) - это преобразование из std::string к std::wstring через такую функцию:
C++
1
2
3
4
5
6
7
8
9
10
11
std::wstring s2ws(const std::string& s)
{
    int len;
    int slength = (int)s.length() + 1;
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
    wchar_t* buf = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
    std::wstring r(buf);
    delete[] buf;
    return r;
}
Память просто выделил как MAX_PATH+1

Добавлено через 3 минуты
to DemolitionMan:
У Вас в примере строка - это char*, а у меня - WCHAR*. Я не нашел процедуры перевода из wchar* в char*. Хотя если честно тут я вообще не понял почему нужно переводить, ведь WCHAR - это надстройка над char, в зависимости от того, какая стоит кодировка проекта. И вроде как должно быть автоматически в зависимости от настройки под что мы пишем - Unicode или нет. Я пытаюсь писать под Unicode, и не понимаю зачем переводить строки в char*.
nmcf
4303 / 3724 / 1255
Регистрация: 14.04.2014
Сообщений: 14,580
01.08.2016, 12:46     Не могу разбить строку по разделителю #7
Цитата Сообщение от nwpepper Посмотреть сообщение
Строка получается таким кодом:
Это называется возврат локального объекта. Исправляй.

Если вот это выполнить, правильно выводит?
C++
1
2
WCHAR s[] = L"D:\\ANT\\Act_2016_07.rar";
wcout << s << endl;
nwpepper
0 / 0 / 0
Регистрация: 01.08.2016
Сообщений: 7
01.08.2016, 13:02  [ТС]     Не могу разбить строку по разделителю #8
to nmfc:
Выполнил Ваш код. Также показывает черное окно. Строку не выводит.

P/S. Т.е. в с++ нельзя инициализировать переменную внутри функции, заполнить её и отдать в вызывающий код?
hoggy
5228 / 2119 / 403
Регистрация: 15.11.2014
Сообщений: 4,806
Завершенные тесты: 1
01.08.2016, 13:19     Не могу разбить строку по разделителю #9
Цитата Сообщение от nwpepper Посмотреть сообщение
Т.е. в с++ нельзя инициализировать переменную внутри функции, заполнить её и отдать в вызывающий код?
можно.

если вот это:
C++
1
WCHAR* getstrForCopyFiles(WCHAR* myStr, std::vector<std::string> &massID)
заменить на это:
C++
1
std::wstring getstrForCopyFiles(WCHAR* myStr, std::vector<std::string> &massID)
nwpepper
0 / 0 / 0
Регистрация: 01.08.2016
Сообщений: 7
01.08.2016, 13:41  [ТС]     Не могу разбить строку по разделителю #10
Цитата Сообщение от hoggy Посмотреть сообщение
WCHAR* getstrForCopyFiles(WCHAR* myStr, std::vector<std::string> &massID)
Цитата Сообщение от hoggy Посмотреть сообщение
std::wstring getstrForCopyFiles(WCHAR* myStr, std::vector<std::string> &massID)
А если мне нужно значение именно WCHAR? Или например как быть если это фабрика классов? Должна быть возможность создать объект в функции и вернуть его.

Я отвлекся. Почему код:
C++
1
2
WCHAR s[] = L"D:\\ANT\\Act_2016_07.rar";
std::wcout << s << std::endl;
ничего не выводит в консоль?

Добавлено через 4 минуты
Потому что консоль - 32-ух битная, а строка типа WCHAR - 64-х битная?
hoggy
5228 / 2119 / 403
Регистрация: 15.11.2014
Сообщений: 4,806
Завершенные тесты: 1
01.08.2016, 13:44     Не могу разбить строку по разделителю #11
Цитата Сообщение от nwpepper Посмотреть сообщение
А если мне нужно значение именно WCHAR?
http://www.gunsmoker.ru/2008/10/x-y-z.html

Цитата Сообщение от nwpepper Посмотреть сообщение
ничего не выводит в консоль?
попробуйте так:

C++
1
2
3
WCHAR s[] = L"D:\\ANT\\Act_2016_07.rar";
assert(std::wcout && "ERROR: std::wcout is broken");
std::wcout << s << std::endl;
если сработает ассерт,
значит где то выше по коду вы поломали стрим
(например, где то выше по коду вы в него попытались запихать русские буквы,
не установив виндузятную локаль)

если ассерт не сработал,
значит вы нагнули консольку.

здесь уже либо код, либо ждите телепатов.
DemolitionMan
 Аватар для DemolitionMan
22 / 54 / 18
Регистрация: 06.04.2016
Сообщений: 325
01.08.2016, 15:58     Не могу разбить строку по разделителю #12
Цитата Сообщение от nwpepper Посмотреть сообщение
У Вас в примере строка - это char*, а у меня - WCHAR*. Я не нашел процедуры перевода из wchar* в char*. Хотя если честно тут я вообще не понял почему нужно переводить, ведь WCHAR - это надстройка над char, в зависимости от того, какая стоит кодировка проекта. И вроде как должно быть автоматически в зависимости от настройки под что мы пишем - Unicode или нет. Я пытаюсь писать под Unicode, и не понимаю зачем переводить строки в char*.
- а я не понял зачем Вам wchar, который имеет 16-бит или 32-бита или больше в зависимости от системы, т.к. wchar и Unicode - это сделано для китайского языка, чтобы влезли все их десятки тысяч иероглифов. Зачем Вам это, если Вы используете пути на английском языке?
hoggy
5228 / 2119 / 403
Регистрация: 15.11.2014
Сообщений: 4,806
Завершенные тесты: 1
01.08.2016, 17:21     Не могу разбить строку по разделителю #13
Цитата Сообщение от DemolitionMan Посмотреть сообщение
Зачем Вам это, если Вы используете пути на английском языке?
затем что используется WINAPI, где юникод во все поля.

ваш К.О.
DemolitionMan
 Аватар для DemolitionMan
22 / 54 / 18
Регистрация: 06.04.2016
Сообщений: 325
01.08.2016, 17:27     Не могу разбить строку по разделителю #14
Можно Unicode 8-битный использовать(UTF-8, автор ведь по-китайски не говорит, верно?).
hoggy
5228 / 2119 / 403
Регистрация: 15.11.2014
Сообщений: 4,806
Завершенные тесты: 1
01.08.2016, 17:31     Не могу разбить строку по разделителю #15
Цитата Сообщение от DemolitionMan Посмотреть сообщение
Можно Unicode 8-битный использовать
можно.
можно на первый этаж через чердак.

а можно использовать родной для winapi unicode,
и не парить голову ни себе, ни людям.
DemolitionMan
 Аватар для DemolitionMan
22 / 54 / 18
Регистрация: 06.04.2016
Сообщений: 325
01.08.2016, 17:38     Не могу разбить строку по разделителю #16
Хотел еще автору регулярные выражения посоветовать, там все влегкую делается. Остается дело за малым - изучить это.

Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
А можно использовать родной для winapi unicode,
и не парить голову ни себе, ни людям.
- а я думал программирование это и есть головопарка. То что Вы говорите это только Microsoft Visual Studio 2013/2015 или какая там версия у автора? А в Билдере есть такое?
hoggy
5228 / 2119 / 403
Регистрация: 15.11.2014
Сообщений: 4,806
Завершенные тесты: 1
01.08.2016, 17:41     Не могу разбить строку по разделителю #17
Цитата Сообщение от DemolitionMan Посмотреть сообщение
То что Вы говорите это только Microsoft Visual Studio 2013/2015 или какая там версия у автора?
это - windows.
nofx
7 / 7 / 1
Регистрация: 28.10.2012
Сообщений: 85
Завершенные тесты: 1
01.08.2016, 17:46     Не могу разбить строку по разделителю #18
А massID почему в многобайтной кодировке? Может стоит переписать, чтобы не юзать s2ws?
Выложите Ваш проект.
Также мучался c этипими типами, пришел к выводу что лучше использовать TCHAR и LPTSTR (и дописывать "TEXT" вместо "L")
nwpepper
0 / 0 / 0
Регистрация: 01.08.2016
Сообщений: 7
02.08.2016, 04:54  [ТС]     Не могу разбить строку по разделителю #19
Цитата Сообщение от DemolitionMan Посмотреть сообщение
Хотел еще автору регулярные выражения посоветовать, там все влегкую делается. Остается дело за малым - изучить это.
Что такое регулярные выражения я в курсе,спасибо :-)
Но я программирую на 1С в целом. На с++ нужно написать внешнюю компоненту. Уровень знаний - лабы в школе.
Поэтому классов, к-е работают с рег. выражениями в с++ я не знаю стандартных. А сторонние библиотеки подключать во внешнюю dll - не хочется. Задача то простая.

Добавлено через 1 минуту
Цитата Сообщение от nofx Посмотреть сообщение
Выложите Ваш проект.
А подскажите как выложить весь проект? Я с удовольствием поделюсь.

Добавлено через 2 минуты
Цитата Сообщение от nofx Посмотреть сообщение
пришел к выводу что лучше использовать TCHAR и LPTSTR (и дописывать "TEXT" вместо "L")
Вот я также пришел к этому выводу. На практике не могу понять как сделать, потому что одни функции требуют TCHAR, другие - обычный char.

Добавлено через 1 минуту
Цитата Сообщение от DemolitionMan Посмотреть сообщение
UTF-8, автор ведь по-китайски не говорит, верно?
К сожалению, не говорю))
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.08.2016, 06:50     Не могу разбить строку по разделителю
Еще ссылки по теме:

C++ Разбить строку на слова
Разбить строку на слова C++
Как проще всего разбить строку на ряд строк по разделителю? C++

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

Или воспользуйтесь поиском по форуму:
nwpepper
0 / 0 / 0
Регистрация: 01.08.2016
Сообщений: 7
02.08.2016, 06:50  [ТС]     Не могу разбить строку по разделителю #20
После первого прохода цикла строка превращается в строку китайских иероглифов.
Миниатюры
Не могу разбить строку по разделителю  
Yandex
Объявления
02.08.2016, 06:50     Не могу разбить строку по разделителю
Ответ Создать тему
Опции темы

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