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

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

Войти
Регистрация
Восстановить пароль
 
 
nwpepper
0 / 0 / 0
Регистрация: 01.08.2016
Сообщений: 7
#1

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

01.08.2016, 09:48. Просмотров 741. Ответов 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
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Не могу разбить строку по разделителю (C++):

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

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

Разбить строку - C++
Есть строка: Нужно написать функцию, чтобы в результате получилось на выходе например в vector<string> Вот что смог...

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

Разбить строку - C++
У меня есть строка string^ str в неё записано 6 символов. Как мне разбить эту строку на еще три строки в каждой из которых будут по два...

Как разбить строку - C++
Как прочитать такую строку за один раз? Ukraine Kiev Donetsk Odessa и как мне строку разбить на слова и добавить в вектор. ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
nonedark2008
909 / 648 / 134
Регистрация: 28.07.2012
Сообщений: 1,760
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
5320 / 4640 / 1551
Регистрация: 14.04.2014
Сообщений: 18,452
01.08.2016, 12:15 #4
С wcout работает? И какой указатель возвращает getstrForCopyFiles()? Память динамически выделяется или там какой-то буфер выше есть?
0
DemolitionMan
97 / 153 / 47
Регистрация: 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
5320 / 4640 / 1551
Регистрация: 14.04.2014
Сообщений: 18,452
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
Нарушитель
6590 / 2771 / 476
Регистрация: 15.11.2014
Сообщений: 6,125
Завершенные тесты: 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
Нарушитель
6590 / 2771 / 476
Регистрация: 15.11.2014
Сообщений: 6,125
Завершенные тесты: 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
97 / 153 / 47
Регистрация: 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
Нарушитель
6590 / 2771 / 476
Регистрация: 15.11.2014
Сообщений: 6,125
Завершенные тесты: 1
01.08.2016, 17:21 #13
Цитата Сообщение от DemolitionMan Посмотреть сообщение
Зачем Вам это, если Вы используете пути на английском языке?
затем что используется WINAPI, где юникод во все поля.

ваш К.О.
1
DemolitionMan
97 / 153 / 47
Регистрация: 06.04.2016
Сообщений: 992
01.08.2016, 17:27 #14
Можно Unicode 8-битный использовать(UTF-8, автор ведь по-китайски не говорит, верно?).
0
hoggy
Нарушитель
6590 / 2771 / 476
Регистрация: 15.11.2014
Сообщений: 6,125
Завершенные тесты: 1
01.08.2016, 17:31 #15
Цитата Сообщение от DemolitionMan Посмотреть сообщение
Можно Unicode 8-битный использовать
можно.
можно на первый этаж через чердак.

а можно использовать родной для winapi unicode,
и не парить голову ни себе, ни людям.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.08.2016, 17:31
Привет! Вот еще темы с ответами:

Разбить строку на слова - C++
Здравствуйте! Решаю задачу, надо разбить предложение на слова с помощью функции strtok. Делаю вот так но не уверен что это правильно....

разбить строку в массив - C++
Как разбить массив символов в отдельный массив по слову?Я вот что-то написал,проде бы правильно,но когда например ввожу строку &quot;heavy...

Разбить строку на слова - C++
Разбить строку на слова. Все слова записать в отдельную строку. Помогите пожалуйста не получается. #include &lt;iostream&gt; #include...

Как разбить строку - C++
Здравствуйте! Как извлечь из вводимой строки только символы? К примеру, вводим &quot; asd sss 12&quot;, а на выходе получаем asd, sss и 12?...


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

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

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