Консультация № 180522
31.10.2010, 16:10
51.70 руб.
0 11 2
Уважаемые эксперты! Ещё один вопрос из цикла уже заданных: слияние строк в С++ и объединение строки и целой переменной в С++.
Предположим, что некоторая функция возвращает указатель на текстовую строку, которая доподлинно известно содержит следующее:
123\0обычный текст\0
где \0 - это NULL.
Вопрос такой. Необходимо в переменную типа int поместить первую часть текста (т.е. "123") и в переменную типа char вторую часть - "обычный текст\0".
Как на ваш взгляд это может быть организовано?
Спасибо!

Обсуждение

Неизвестный
31.10.2010, 16:41
общий
это ответ
Здравствуйте, Калашников О.А.!

если t это вернувшийся указатель, то целое можно получить следующим способом

i=atoi(t) Ограничение число должно вписываться в int. Если 32-разрядная система то в 2 с небольшим миллиарда. Если 16-разрядная, то в 65536. Также функция учитывает знак.

Для получения указателя на текст(char *)

c=t+strlen(t)+1;//к указателю прибавляем длину строки и он будет указывать на \0. Потом добавляем ещё единичку, чтоб указывал на начало текста.

Если разграничитель не символ конца строки, а просто не цифра, то подойдет функция strtol. И начало текста брать из 2го параметра.
Если условие границы не стандартно, то свой цикл преобразования в число.


Неизвестный
31.10.2010, 16:43
общий
Калашников О.А.:
atoi подходит только в случае строгого соответствия приведенному формату.
давно
Академик
320937
2216
31.10.2010, 17:05
общий
Калашников О.А.:
Добрый вечер! Вариант GCC/Code::Blocks
Код:
// 180522 Вопрос: Калашников О.А. Ответ: lamed
// Предположим, что некоторая функция возвращает указатель на текстовую
// строку, которая доподлинно известно содержит следующее:
// 123\0обычный текст\0
// где \0 - это NULL.
// Вопрос такой. Необходимо в переменную типа int поместить первую часть
// текста (т.е. "123") и в переменную типа char вторую часть - "обычный текст\0".
// Как на ваш взгляд это может быть организовано?
#include <stdio.h>
int main(void)
{
int num;
char s[40];
char *t="123\0обычный текст";

int i;
int j=0;
for (i=0, num=0; t[i]!='\0'; i++)
num = num * 10 + (t[i]-'0');

i++;
while ((s[j++]=t[i++])!='\0')
;
puts(s);
printf("%d\n", num);
system("pause");

return 0;
}

Пример вывода
Код:

Для продолжения нажмите любую клавишу . . .
обычный текст
123


давно
Профессор
230118
3054
31.10.2010, 17:10
общий
Функция sscanf это делает. Но после \0 она читать не будет. Нельзя ее заменить на пробел?
давно
Руководитель
2
547
31.10.2010, 17:14
общий
Гаряка Асмик:
Боюсь, что на пробел заменить не получится.
Неужели нет простого способа в С++ сделать такую штуку?
Например, Перл сделает это так:
($int, $char) = split(/\0/, $string);
где $string - строка "123\0обычный текст\0"
В итоге $int будет содержать число 123, а $char - "обычный текст".
Неизвестный
31.10.2010, 17:34
общий
Гаряка Асмик:
On success, the function returns the number of items succesfully read. This count can match the expected number of readings or fewer, even zero, if a matching failure happens.
In the case of an input failure before any data could be successfully read, EOF is returned.
описание sscanf

Достаточно ей считать число, а к первоначальному указателю прибавить на один больше, чем возвращаемое ею значение, чтобы получить указатель на обычный текст.
давно
Профессор
230118
3054
31.10.2010, 17:42
общий
Vadim22:
Возвращает количество прочитанных переменных, а не указатель.
Неизвестный
31.10.2010, 17:45
общий
Калашников О.А.:
Простых куча.
В int_ будет храниться число. В char_ указатель на обычный текст. Объявления
char * char_;
int int_;

1й способ
sscanf(t,"%d", & int_ );
har_=t+strlen(t)+1

2й способ
int_=atoi(t);
char_=t+strlen(t)+1;

3й способ
int_= strtol(t, &char_, 10); // объявление для использования должно быть long int int_;
char++;//если вы уверены, что разделитель 0
Неизвестный
31.10.2010, 17:55
общий
Гаряка Асмик:
Извините, ошибся.
давно
Профессор
230118
3054
31.10.2010, 17:57
общий
это ответ
Здравствуйте, Калашников О.А.!

Программа работает при указанных Вами условиях.
Код:
#include <stdlib.h>
#include <stdio.h>
#include <cstdio>
#include <cstring>

int main(int argc, char* argv[])
{

char *str="123\0обычный текст";
int a;
char *text=new char[100];
sscanf(str,"%d",&a);
strcpy(text,str+strlen(str)+1);
delete[] text;
return 0;
}
5
То, что надо! Спасибо!
Неизвестный
01.11.2010, 07:24
общий
Калашников О.А.:
Неужели нет простого способа в С++ сделать такую штуку?


Есть функция strtok, которая режет строчку по делимитерам.

Примерно так:

Код:
	char *psz = strtok(szData, " "); // режем по пробелу
do
{
ps[size++] = psz;// для примера
}
while(psz = strtok(NULL, " ")); //... и продолжаем по пробелу резать дальше
//... psz будет каждый раз содержать указатель на новый кусочек


Не уверен, правда, что в качестве делимитера можно использовать null, зато там можно указать список, а не один символ, т.е

Код:
	psz = strtok(szText, _T("\t\n;,."));
//...


Важное замечаение: strtok вроде как использует какие-то статические переменные под данные, поэтому нельзя использовать вложенные вызовы - данные теряются. Т.е. нельзя, к примеру, разрезая текст на предложения по точкам, потом внутри цикла ещё каждое предложение резать на слова по пробелам.
Ну это, видимо, только если используется NULL в качестве первого параметра. Знающие детально этот вопрос, поправьте
Форма ответа