Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
nwpepper
0 / 0 / 0
Регистрация: 01.08.2016
Сообщений: 7
1

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

01.08.2016, 09:48. Просмотров 895. Ответов 25
Метки нет (Все метки)

Суть такая: Делаю задачу копирования информации в папку на всех устройствах.
Есть строка пути в виде: Откуда|Куда;Откуда|Куда;... и.т.д.
Не могу распарсить на токены. Я путаюсь с 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. Подскажите куда копать или что я не так делаю.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.08.2016, 09:48
Ответы с готовыми решениями:

Разбить строку по заданному разделителю
Код ниже может разбить строку по разделителю, который заранее указан в char...

Как проще всего разбить строку на ряд строк по разделителю?
Пусть например есть строка "abc;dasfadfa;asfadsfv". Надо разбить ее...

Разбить строку
Просьба написать программу на С++ , которая разбивает строку длинной в 200...

Разбить строку
У меня есть строка string^ str в неё записано 6 символов. Как мне разбить эту...

Разбить строку
Есть строка: Нужно написать функцию, чтобы в результате получилось на...

25
nonedark2008
1052 / 786 / 220
Регистрация: 28.07.2012
Сообщений: 2,195
01.08.2016, 10:14 2
nwpepper, я ни за что не отвечаю, но верю, что вместо "%s" в wprintf нужно использовать "%ls".
0
nwpepper
0 / 0 / 0
Регистрация: 01.08.2016
Сообщений: 7
01.08.2016, 11:27  [ТС] 3
Спасибо, поставил. Но не помогло.
Может по скриншотам кто поможет разобраться.
0
Миниатюры
Не могу разбить строку по разделителю   Не могу разбить строку по разделителю   Не могу разбить строку по разделителю  

Не могу разбить строку по разделителю  
nmcf
6274 / 5577 / 2537
Регистрация: 14.04.2014
Сообщений: 23,468
01.08.2016, 12:15 4
С wcout работает? И какой указатель возвращает getstrForCopyFiles()? Память динамически выделяется или там какой-то буфер выше есть?
0
DemolitionMan
129 / 155 / 87
Регистрация: 06.04.2016
Сообщений: 992
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;
}
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*.
0
nmcf
6274 / 5577 / 2537
Регистрация: 14.04.2014
Сообщений: 23,468
01.08.2016, 12:46 7
Цитата Сообщение от nwpepper Посмотреть сообщение
Строка получается таким кодом:
Это называется возврат локального объекта. Исправляй.

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

P/S. Т.е. в с++ нельзя инициализировать переменную внутри функции, заполнить её и отдать в вызывающий код?
0
hoggy
Нарушитель
Эксперт С++
7087 / 3130 / 648
Регистрация: 15.11.2014
Сообщений: 7,209
Завершенные тесты: 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)
0
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-х битная?
0
hoggy
Нарушитель
Эксперт С++
7087 / 3130 / 648
Регистрация: 15.11.2014
Сообщений: 7,209
Завершенные тесты: 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;
если сработает ассерт,
значит где то выше по коду вы поломали стрим
(например, где то выше по коду вы в него попытались запихать русские буквы,
не установив виндузятную локаль)

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

здесь уже либо код, либо ждите телепатов.
0
DemolitionMan
129 / 155 / 87
Регистрация: 06.04.2016
Сообщений: 992
01.08.2016, 15:58 12
Цитата Сообщение от nwpepper Посмотреть сообщение
У Вас в примере строка - это char*, а у меня - WCHAR*. Я не нашел процедуры перевода из wchar* в char*. Хотя если честно тут я вообще не понял почему нужно переводить, ведь WCHAR - это надстройка над char, в зависимости от того, какая стоит кодировка проекта. И вроде как должно быть автоматически в зависимости от настройки под что мы пишем - Unicode или нет. Я пытаюсь писать под Unicode, и не понимаю зачем переводить строки в char*.
- а я не понял зачем Вам wchar, который имеет 16-бит или 32-бита или больше в зависимости от системы, т.к. wchar и Unicode - это сделано для китайского языка, чтобы влезли все их десятки тысяч иероглифов. Зачем Вам это, если Вы используете пути на английском языке?
0
hoggy
Нарушитель
Эксперт С++
7087 / 3130 / 648
Регистрация: 15.11.2014
Сообщений: 7,209
Завершенные тесты: 1
01.08.2016, 17:21 13
Цитата Сообщение от DemolitionMan Посмотреть сообщение
Зачем Вам это, если Вы используете пути на английском языке?
затем что используется WINAPI, где юникод во все поля.

ваш К.О.
1
DemolitionMan
129 / 155 / 87
Регистрация: 06.04.2016
Сообщений: 992
01.08.2016, 17:27 14
Можно Unicode 8-битный использовать(UTF-8, автор ведь по-китайски не говорит, верно?).
0
hoggy
Нарушитель
Эксперт С++
7087 / 3130 / 648
Регистрация: 15.11.2014
Сообщений: 7,209
Завершенные тесты: 1
01.08.2016, 17:31 15
Цитата Сообщение от DemolitionMan Посмотреть сообщение
Можно Unicode 8-битный использовать
можно.
можно на первый этаж через чердак.

а можно использовать родной для winapi unicode,
и не парить голову ни себе, ни людям.
0
DemolitionMan
129 / 155 / 87
Регистрация: 06.04.2016
Сообщений: 992
01.08.2016, 17:38 16
Хотел еще автору регулярные выражения посоветовать, там все влегкую делается. Остается дело за малым - изучить это.

Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
А можно использовать родной для winapi unicode,
и не парить голову ни себе, ни людям.
- а я думал программирование это и есть головопарка. То что Вы говорите это только Microsoft Visual Studio 2013/2015 или какая там версия у автора? А в Билдере есть такое?
0
hoggy
Нарушитель
Эксперт С++
7087 / 3130 / 648
Регистрация: 15.11.2014
Сообщений: 7,209
Завершенные тесты: 1
01.08.2016, 17:41 17
Цитата Сообщение от DemolitionMan Посмотреть сообщение
То что Вы говорите это только Microsoft Visual Studio 2013/2015 или какая там версия у автора?
это - windows.
0
nofx
7 / 7 / 5
Регистрация: 28.10.2012
Сообщений: 126
Завершенные тесты: 3
01.08.2016, 17:46 18
А massID почему в многобайтной кодировке? Может стоит переписать, чтобы не юзать s2ws?
Выложите Ваш проект.
Также мучался c этипими типами, пришел к выводу что лучше использовать TCHAR и LPTSTR (и дописывать "TEXT" вместо "L")
1
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, автор ведь по-китайски не говорит, верно?
К сожалению, не говорю))
0
nwpepper
0 / 0 / 0
Регистрация: 01.08.2016
Сообщений: 7
02.08.2016, 06:50  [ТС] 20
После первого прохода цикла строка превращается в строку китайских иероглифов.
0
Миниатюры
Не могу разбить строку по разделителю  
02.08.2016, 06:50
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.08.2016, 06:50

Как разбить строку
Здравствуйте! Как извлечь из вводимой строки только символы? К примеру,...

Разбить строку на 3 значения
Всем доброго времени суток! Возникла проблема: не удается разбить строку...

Разбить строку на 4 палиндрома
Здравствуйте! Условие: Дана строка s.Нужно разбить ее на 4 палиндрома. ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

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