Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / он-лайн преобразование char* в char[] / 23 сообщений из 23, страница 1 из 1
07.10.2013, 09:02
    #38418473
andreybs
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
Нужно распарсить строку параметров запуска приложения:

Код: plaintext
1.
int main(int argc, char* argv[]) // пример параметров: -name1:value1,value2 -name2:value3



Находим пример использования функции strtok:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
	char str[] ="- This, a sample string.";
	char * pch;
	char * context = NULL;
	char *sep = " ,.-";
	printf ("Splitting string \"%s\" into tokens:\n",str);
	pch = strtok_s (str,sep, &context);
	while (pch != NULL)
	{
		printf ("%s\n",pch);
		pch = strtok_s (NULL, sep, &context);
	}



Проблема в том, что функция обращается к исходной строке, как к массиву (char[]), а в argv хранятся константы (char*). В итоге, приведенный пример работать не будет - если в нем заменить char str[] на char *str, то произойдет ран-тайм-ошибка.

Это чтобы пример работал для парсинга, нужно объявить массив, задать ему размер по длине строки, скопировать в него данные... Кривотина какая то получится, прям хоть самому пиши функцию парсинга.

Как обойти проблему?
...
Рейтинг: 0 / 0
07.10.2013, 11:28
    #38418648
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
andreybs,
При вызове main параметры уже разбиты на токены, самому это делать уже не нужно.

У тебя же параметр входной в main — это массив строк, массив указателей на char.там уже лежат разбитые на токены строки вызова.
...
Рейтинг: 0 / 0
07.10.2013, 11:57
    #38418683
?
?
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
andreybsПроблема в том, что функция обращается к исходной строке, как к массиву (char[]), а в argv хранятся константы (char*). В итоге, приведенный пример работать не будет - если в нем заменить char str[] на char *str, то произойдет ран-тайм-ошибка.
Что-то ты гонишь. Не, если в этом примере заменить char str[] на char *str, оно можнт и упадет (от компилятора зависит), но какоен это имееет отношение к argv?
...
Рейтинг: 0 / 0
07.10.2013, 11:58
    #38418684
?
?
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
MasterZiv, ему видимо надо не (только) по пробелам.
...
Рейтинг: 0 / 0
07.10.2013, 12:10
    #38418713
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
andreybs,

Строки в argv точно не константы.
...
Рейтинг: 0 / 0
07.10.2013, 12:13
    #38418719
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
andreybsесли в нем заменить char str[] на char *str, то произойдет ран-тайм-ошибка
В нормальных компиляторах в первую очередь произойдет компайл-тайм ошибка, потому что присвоение строкового литерала в неконстантный указатель - это ошибка.
...
Рейтинг: 0 / 0
07.10.2013, 12:43
    #38418753
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
andreybsПроблема в том, что функция обращается к исходной строке, как к массиву (char[]), а в argv хранятся константы (char*).


Нет, там хранятся не константы. Даже если там храняться константы, ты можешь предварительно скопировать их в сбой буфер.

andreybsВ итоге, приведенный пример работать не будет -



Будет, если написать правильно.

andreybsесли в нем заменить char str[] на char *str, то произойдет ран-тайм-ошибка.


Код показывай...

А вообще для этого есть уже готовые компонетны, типа GNU options или boost programm options.
...
Рейтинг: 0 / 0
07.10.2013, 13:07
    #38418788
valkot
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
andreybs, а вы пробовали? Ф-ция strtok_s ждет тип указателя char *, _именно_ этого типа указатели лежат в массиве указателей argv[]. Просто передавайте во внешнем цикле в стрток_с
argv[i] от i=1 до i<argc
strtok_s(argv[i], ...);
и не морочьте голову.
...
Рейтинг: 0 / 0
07.10.2013, 13:11
    #38418794
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
Дайте-ж ему ответить-то.
...
Рейтинг: 0 / 0
07.10.2013, 19:41
    #38419405
andreybs
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
Почитал рекомендации, попробовал разное.

Выводы такие:

Мой проект юникодный, переделал пример под него с wcstok_s:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
	_TCHAR * pch;
	_TCHAR * context = NULL;
	_TCHAR * sep = L":,";
	pch = wcstok_s (argv[1], sep, &context);
	while (pch != NULL)
	{
		wprintf (L"%s\n",pch);
		pch = wcstok_s (NULL, sep, &context);
	}



- так работает, argv парсится.

Не понятно, почему не работает так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
		_TCHAR * str = L"- This, a sample string.";
// _TCHAR str[] = L"- This, a sample string."; // а так работает!
	_TCHAR * pch;
	_TCHAR * context = NULL;
	_TCHAR * sep = L":, ";
	pch = wcstok_s (str, sep, &context);
	while (pch != NULL)
	{
		wprintf (L"%s\n",pch);
		pch = wcstok_s (NULL, sep, &context);
	}



argv[i] объявлен так же, как и str - _TCHAR*. Конечно, argv - массив строк, но ведь каждая строка объявлена как _TCHAR*.

Если str объявить типом _TCHAR[] вместо _TCHAR*, то второй пример заработает. Это можно объяснить тем, что в первом случае мы имеем read-only строку, а во втором случае массив (на форуме как-то так описывалась разница в работе char* и char[]).
...
Рейтинг: 0 / 0
07.10.2013, 19:49
    #38419410
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
andreybs,

Код: plaintext
1.
_TCHAR * str = L"- This, a sample string.";


Так нельзя делать
Anatoly Moskovskyпотому что присвоение строкового литерала в неконстантный указатель - это ошибка
...
Рейтинг: 0 / 0
07.10.2013, 21:45
    #38419490
andreybs
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
Anatoly Moskovskyandreybs,

Код: plaintext
1.
_TCHAR * str = L"- This, a sample string.";


Так нельзя делать
Anatoly Moskovskyпотому что присвоение строкового литерала в неконстантный указатель - это ошибка

Ну почему же? Компилятор это пропускает. И если работать со строкой, как с константой, то ран-тайм ошибки не будет.

Код: plaintext
1.
2.
3.
	_TCHAR * s = L"Test string.";
	_TCHAR ch1 = s[0]; // читать из строки можно, ошибки нет
	s[0] = L'e'; // писать в строку нельзя - ошибка доступа к странице памяти



Видимо, wcstok_s (и подобные функции) пытаются менять содержимое строки, от того и вылетает ошибка?...
...
Рейтинг: 0 / 0
07.10.2013, 23:40
    #38419547
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
andreybsНу почему же? Компилятор это пропускает. И если работать со строкой, как с константой, то ран-тайм ошибки не будет.
Смените компилятор на нормальный.
Ну и литерал - это и есть константа. Почему вас удивляет что при попытке изменить ее вы получаете не то что хотели? Работайте с ней как с константой, честно - через const char*.
...
Рейтинг: 0 / 0
08.10.2013, 02:20
    #38419604
valkot
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
andreybsПочитал рекомендации, попробовал разное.

Выводы такие:

Мой проект юникодный, переделал пример под него с wcstok_s:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
	_TCHAR * pch;
	_TCHAR * context = NULL;
	_TCHAR * sep = L":,";
	pch = wcstok_s (argv[1], sep, &context);
	while (pch != NULL)
	{
		wprintf (L"%s\n",pch);
		pch = wcstok_s (NULL, sep, &context);
	}



- так работает, argv парсится.

Не понятно, почему не работает так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
		_TCHAR * str = L"- This, a sample string.";
// _TCHAR str[] = L"- This, a sample string."; // а так работает!
	_TCHAR * pch;
	_TCHAR * context = NULL;
	_TCHAR * sep = L":, ";
	pch = wcstok_s (str, sep, &context);
	while (pch != NULL)
	{
		wprintf (L"%s\n",pch);
		pch = wcstok_s (NULL, sep, &context);
	}



argv[i] объявлен так же, как и str - _TCHAR*. Конечно, argv - массив строк, но ведь каждая строка объявлена как _TCHAR*.

Если str объявить типом _TCHAR[] вместо _TCHAR*, то второй пример заработает. Это можно объяснить тем, что в первом случае мы имеем read-only строку, а во втором случае массив (на форуме как-то так описывалась разница в работе char* и char[]).

когда вы объявляете
char *str = "ляляля";
или
wchar_t *str = L"ляляля";
в ф-ции, вы создаете в стеке переменную _указатель_ на строку, и присваиваете ему адресс строки "ляляля", которую компилятор создает в ридонли секции данных. Когда вы объявляете
chаr str[] = "ляляля";
то вы создаете в стеке переменную _массив символов_ - строковой буфер, он конечно writeable.
argv[] - это массив указателей на тоже writeable строки, - только они в куче, а не на стеке.
И конечно все эти ф-ции пишут в строки, а именно - они меняют по очереди те символы которые вы указали как разделители на NULL. Они не выходят за границы строк, но меняют их разбивая на подстроки токены.
Код: c
1.
2.
3.
4.
5.
6.
7.
for(int i=1; i<argc; ++i){
  pch = strtok_s(argv[i], sep, &context);
  while(pch){
    printf("%s\n", pch);
    pch = strtok_s(NULL, sep, &context);
    //...
  }
}
...
Рейтинг: 0 / 0
08.10.2013, 10:51
    #38419857
andreybs
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
Anatoly MoskovskyСмените компилятор на нормальный.


Дык Майкрософт же!? :) VS2012 ultimate со всеми SP...

valkotкогда вы объявляете
char *str = "ляляля";
или
wchar_t *str = L"ляляля";
в ф-ции, вы создаете в стеке переменную _указатель_ на строку, и присваиваете ему адресс строки "ляляля", которую компилятор создает в ридонли секции данных. Когда вы объявляете
chаr str[] = "ляляля";
то вы создаете в стеке переменную _массив символов_ - строковой буфер, он конечно writeable.
argv[] - это массив указателей на тоже writeable строки, - только они в куче, а не на стеке.
И конечно все эти ф-ции пишут в строки, а именно - они меняют по очереди те символы которые вы указали как разделители на NULL. Они не выходят за границы строк, но меняют их разбивая на подстроки токены.
Код: c
1.
2.
3.
4.
5.
6.
for(int i=1; i  pch = strtok_s(argv[i], sep, &context);
  while(pch){
    printf("%s\n", pch);
    pch = strtok_s(NULL, sep, &context);
    //...
  }
}


Вполне понятное объяснение, спасибо.
...
Рейтинг: 0 / 0
08.10.2013, 21:08
    #38420883
andreybs
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
Небольшое дополнение.
В итоге воспользовался функцией CString::Tokenize.
Проста в использовании и не меняет исходную строку в отличие от strtok_s и ей подобных.
...
Рейтинг: 0 / 0
08.10.2013, 22:38
    #38420924
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
andreybs, а не влом для такой малости в проект MFC засовывать?
Просто для решения именно этой цели есть и более легкие библиотеки...
...
Рейтинг: 0 / 0
09.10.2013, 06:56
    #38421037
?
?
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
MasterZivandreybs, а не влом для такой малости в проект MFC засовывать?
Просто для решения именно этой цели есть и более легкие библиотеки... http://msdn.microsoft.com/en-us/library/vstudio/ekdt199a.aspx
...
Рейтинг: 0 / 0
09.10.2013, 08:50
    #38421063
andreybs
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
MasterZiv,

CString уже используется в проекте в других местах. Какие более "легкие" решения можете предложить?
...
Рейтинг: 0 / 0
09.10.2013, 13:26
    #38421485
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
andreybs,

boost program options, boost regex, gnu getoptions
и много других.

Кажется, я уже говорил.
...
Рейтинг: 0 / 0
09.10.2013, 13:48
    #38421518
valkot
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
MasterZivandreybs,

boost program options, boost regex, gnu getoptions
и много других.

Кажется, я уже говорил.
те прикручивать левую гнуЪ фигню - легче чем родной мфц, который к тому же уже используется в проекте?
А чем собственно плох метод использования исходных ф-ций с которых все началось? Ну разбивают они строки ну и чем это здесь плохо? Вы узнаете свои опции, парся эти строки, транслируете это в свое внутреннее представление, принимаете соотв. решения и все, текстовый ввод сделал свое дело. Вы же не будете многократно пережовывать тот текстовый ввод.)
...
Рейтинг: 0 / 0
09.10.2013, 19:04
    #38422025
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
те прикручивать левую гнуЪ фигню - легче чем родной мфц, который к тому же уже используется в проекте?

Там автор говорил где-то про то, что MFC уже используется в проекте ?
...
Рейтинг: 0 / 0
10.10.2013, 13:27
    #38422872
valkot
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
он-лайн преобразование char* в char[]
MasterZiv,

andreybsMasterZiv,

CString уже используется в проекте в других местах. Какие более "легкие" решения можете предложить?
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / он-лайн преобразование char* в char[] / 23 сообщений из 23, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]