Добрый день. Помогите, плиз, кто знает, как:
Есть массив char a[]="12345678".
Необходимо поменять местами элементы 1 и 2, 3 и 4, 5 и 6, 7 и 8.
Т.е. получится 21436587 и ....
Получившийся массив символов преобразовать в массив int, причем ...
1-й элемент должен стать 0х21, 2-й 0х43, 0х65 и 0х87.
Т.е. массив из шестнадцатиричных цифр, ну или их десятичных эквивалентов.Заранее спасибо.
>Добрый день. Помогите, плиз, кто знает, как:
>>Добрый день. Помогите, плиз, кто знает, как:
>
>http://www.opennet.me/openforum/vsluhforumID9/6109.htmlСпасибо, но это не правильный ответ.
>>>Добрый день. Помогите, плиз, кто знает, как:
>>
>>http://www.opennet.me/openforum/vsluhforumID9/6109.html
>
>Спасибо, но это не правильный ответ.Ответ-то как раз правильный - RTFM!
>Добрый день. Помогите, плиз, кто знает, как:
>Есть массив char a[]="12345678".
>Необходимо поменять местами элементы 1 и 2, 3 и 4, 5 и
>6, 7 и 8.
>Т.е. получится 21436587 и ....
>Получившийся массив символов преобразовать в массив int, причем ...
>1-й элемент должен стать 0х21, 2-й 0х43, 0х65 и 0х87.
>Т.е. массив из шестнадцатиричных цифр, ну или их десятичных эквивалентов.
>И чему сейчас студентов учат?
#include <cstdio> // Для printf
#include <algorithm> // Для std::swapusing std::swap;
int main()
{
// Это, собственно, массив, который у тебя есть.
char data[] = "12345678";// Необходимо поменять местами элементы 1 и 2, 3 и 4, 5 и 6, 7 и 8.
// Т.е. получится 21436587 и ....
// Да не вопрос вообще.swap(data[0], data[1]);
swap(data[2], data[3]);
swap(data[4], data[5]);
swap(data[6], data[7]);// Получившийся массив символов преобразовать в массив int, причем ...
// 1-й элемент должен стать 0х21, 2-й 0х43, 0х65 и 0х87.
// Т.е. массив из шестнадцатиричных цифр, ну или их десятичных эквивалентов.
//
// И что, за этим дело стало? Вот, пожалуйста:int res[4];
for (int i = 1; i <= 4; ++i)
{
const int dst_offset = i - 1;
const int src_offset = i * 2 - 2;
res[dst_offset] = data[src_offset] - '0';
res[dst_offset] *= 16;
res[dst_offset] += data[src_offset + 1] - '0';
}// Не верится? Давай проверим:
printf("%#x, %#x, %#x, %#x\n", res[0], res[1], res[2], res[3]);return 0;
}>Заранее спасибо.
С тебя пиво :-)
>(int i = 1; i <= 4; ++i)
> {
> const int dst_offset = i - 1;
> const int src_offset = i * 2 - 2;
> res[dst_offset] = data[src_offset] - '0';
> res[dst_offset] *= 16;
> res[dst_offset] += data[src_offset + 1] - '0';
> }
>
> // Не верится? Давай проверим:
> printf("%#x, %#x, %#x, %#x\n", res[0], res[1], res[2], res[3]);
>Наверняка туда будешь заливать буквы A,B,C и тд, так что программку придется доработать!
JetSnaiL - не тебе конечно ;-))
>>(int i = 1; i <= 4; ++i)
>> {
>> const int dst_offset = i - 1;
>> const int src_offset = i * 2 - 2;
>> res[dst_offset] = data[src_offset] - '0';
>> res[dst_offset] *= 16;
>> res[dst_offset] += data[src_offset + 1] - '0';
>> }
>>
>> // Не верится? Давай проверим:
>> printf("%#x, %#x, %#x, %#x\n", res[0], res[1], res[2], res[3]);
>>
>
>Наверняка туда будешь заливать буквы A,B,C и тд, так что программку придется
>доработать!
>
>JetSnaiL - не тебе конечно ;-))Ребят, спасибо огромное. Поменять местами элементы было не проблема. Проблема стояла в переводе в hex.
P.S.: я не студент! И нужно было для перевода номера в формат PDU (http://www.dreamfabric.com/sms/).
>Наверняка туда будешь заливать буквы A,B,C и тд, так что программку придется
>доработать!
>
>JetSnaiL - не тебе конечно ;-))Несомненно нужно как можно больше возможных нестандартных ситуаций предусмотреть. Но к примеру то это не относится. Это очень простой пример, хорошие программы так никогда не выглядят :)
>>Наверняка туда будешь заливать буквы A,B,C и тд, так что программку придется
>>доработать!
>>
>>JetSnaiL - не тебе конечно ;-))
>
>Несомненно нужно как можно больше возможных нестандартных ситуаций предусмотреть. Но к примеру
>то это не относится. Это очень простой пример, хорошие программы так
>никогда не выглядят :)Ну это понятное дело. Для меня не ясен был алгорит преобразования в hex.
>Для меня не ясен был алгорит преобразования в hex.sprintf %x отменили?
>>Для меня не ясен был алгорит преобразования в hex.
>
>sprintf %x отменили?Извините, но я Вас, кажется, не понимаю.
Не могли бы Вы наглядно продемонстрировать, как в данном случае можно оптимально использовать sprintf?
>Извините, но я Вас, кажется, не понимаю.
>Не могли бы Вы наглядно продемонстрировать, как в данном случае можно оптимально
>использовать sprintf?А где в задаче написано "оптимально"? :)
Перечитал задачу. Понял что "преобразование в hex" тут совершенно не при чем. Бери по два символа, добавляй в конце 0 и используй strtol(3).
>>Извините, но я Вас, кажется, не понимаю.
>>Не могли бы Вы наглядно продемонстрировать, как в данном случае можно оптимально
>>использовать sprintf?
>
>А где в задаче написано "оптимально"? :)Любое решение задачи должно быть максимально оптимальным (о как закрутил). И оптимальное решение задачи - не задача, а само-собой разумеющееся. Представте, что Вы - не студент, а такой себе разработчик, на который возложено много ответственности. Вам ставят задачу, вы ее решаете через ЖПУ. И вот заказчик спрашивает - а чего все так медленно (к примеру) работает? А вы ему - а что, кто-то просил решить вашу задачу оптимально?
>Перечитал задачу. Понял что "преобразование в hex" тут совершенно не при чем.
>Бери по два символа, добавляй в конце 0 и используй strtol(3).Да, как я писал ниже, можно использовать strtol. Однако для этого нужно будет выделить буфер из 3-х байт (sizeof(char) * 3), затем скоприровать в него два байта, и добавить еще один. А только потом вызывать strtol. Это, думаете, хорошее решение? Легче взять strtol и переделать его так, чтобы он не расчитывал на завершающий символ, а ориентировался на размерность (что я, собственно, и сделал).
>Любое решение задачи должно быть максимально оптимальным (о как закрутил).Не факт. Оптимальным должно быть только то что должно быть оптимальным (закрутил еще круче). Все остальное должно быть быстроразрабатываемым и понятным для других :)
Иначе все языки программирования ограничивались бы ассемблерами, а скриптов бы не было как класса :)>Да, как я писал ниже, можно использовать strtol. Однако для этого нужно
>будет выделить буфер из 3-х байт (sizeof(char) * 3), затем скоприровать
>в него два байта, и добавить еще один. А только потом
>вызывать strtol. Это, думаете, хорошее решение?Вполне приемлимое, если не надо делать туеву хучу таких операций в секунду.
> Легче взять strtol и переделать
>его так, чтобы он не расчитывал на завершающий символ, а ориентировался
>на размерность (что я, собственно, и сделал).... и убил на эту ерунду в 10 раз больше времени чем надо было. Причем получил нечитабельный код, по которому с первого взгляда непонятно что делается. Что делает strtol - знают все (кто не знает - набирает man strtol и тоже знает).
>
>Вполне приемлимое, если не надо делать туеву хучу таких операций в секунду.
>Мне легче было написать так, чем возиться с strtol.
>... и убил на эту ерунду в 10 раз больше времени чем
>надо было. Причем получил нечитабельный код, по которому с первого взгляда
>непонятно что делается. Что делает strtol - знают все (кто не
>знает - набирает man strtol и тоже знает).Я? Что Вы! Вы заблуждаетесь. Это я прошел много лет назад, а нароботочки то всегда со мной, поэтому я потратил не больше 30-ти секунд на всю эту кухню. Если бы понадобилось больше времени, я вообще не взялся бы помогать с решением такой банальной задачи.
А по поводу читабельности кода... Хм, вполне читабельно все получилось.
Единсвенная вещь, которая все портит - это цикл. Но он тут просто потому, что мне лень было писать пару дополнительных строк с пркатически идентичным кодом. (кстати, было бы более оптимально, не уверен, что оптимизатор разложит такой фикл, хотя... ммм).
>Я? Что Вы! Вы заблуждаетесь.Не, я не про данный конкретный случай и не про тебя, а про оптимизацию вообще. Она далеко не всегда имеет смысл, в подавляющем большинстве случаев играют другие приоритеты - надежность / переносимость / скорость разработки / читабельность кода и т.д.
>Не, я не про данный конкретный случай и не про тебя,
> а про оптимизацию вообще. Она далеко не всегда имеет смысл, в подавляющем
>большинстве случаев играют другие приоритеты - надежность / переносимость / скорость
>разработки / читабельность кода и т.д.Ха, вот это в точку. Оптимизация - самый последний шаг в разработке. Часто никогда не наступающий без особой необходимости. Но это в реальной жизни, а до того надо обучиться. Тут на лицо учения.
И, кстати, пример такого strtol самописного я привел не случайно. Мы на работу недавно взяли новичка, выпускника. Оказалось, что он не имеет абсолютно никакого понятия, как реализованы функции подобного рода. А нам нужены были преобразования из сырых данных, не разделяемых никакими пробелами и '\0'-ми, причем без промежуточных буферов, копирования и пр. Может быть мой пример поможет кому-то в будущем прийдя на работу знать, как такое вообще можно провернуть.
>
>Ха, вот это в точку. Оптимизация - самый последний шаг в разработке.
>Часто никогда не наступающий без особой необходимости. Но это в реальной
>жизни, а до того надо обучиться.Согласен. Но надо именно УЧИТЬСЯ, а не делать copy+paste+print+зачет. Именно поэтому я принципиально не помогаю задающим такие вопросы.
>Может быть мой пример поможет кому-то в будущем прийдя на работу знать,
>как такое вообще можно провернуть.Боюсь что это поможет кому-то сдать лабораторную работу, не вникая в суть реализации, а вы потом опять возьмете на работу якобы "программиста на C", который не будет различать числа и их ASCII-представление.
Наступили на больную мозоль :)
начнем с того, что сильно накручено. Все проще делается. Зачем swap с подключением доп.библиотек? Что два значения через переменную непоменять?
>(что я, собственно, и сделал)Да, кстати, раз уж пошла речь про оптимальность. s/*16/<<4/ :-)
>>(что я, собственно, и сделал)
>
>Да, кстати, раз уж пошла речь про оптимальность. s/*16/<<4/ :-)[~]o (пиво :-))
>
>[~]o (пиво :-))Вообще-то компиляторы еще с середины 90-х это сами делают.
Это был пример бессмысленной оптимизации. *16 более читабельно чем <<4, поэтому все-таки лучше *16, а оптимизировать можно до бесконечности :-)
>Добрый день. Помогите, плиз, кто знает, как:Ну, я не программист, поэтому может кривовато, но работает. Мож позже кто получше напишет
#include <stdio.h>
main()
{
char buf,a[]="1234567890";
int mas_int[5],j,i=0;
j=0;
while (a[i]&&a[i+1]) /*проверка a[i+1] необходима, если в массиве нечетное кол-во эл-тов*/
{
buf=a[i];
a[i]=a[i+1];
a[i+1]=buf;
mas_int[j]=(a[i]-48)*16+(a[i+1]-48);
printf ("%x\n", mas_int[j]);
i=i+2;
j++;
};
}
>Ну, я не программист,
> поэтому может кривовато, но работает.
> Мож позже кто
>получше напишет
>
>#include <stdio.h>
>
>main()
>{
> char buf,a[]="1234567890";
>
> int mas_int[5],j,i=0;
> j=0;
> while (a[i]&&a[i+1]) /*проверка a[i+1] необходима, если в массиве нечетное кол-во
>эл-тов*/
> {
> buf=a[i];
> a[i]=a[i+1];
> a[i+1]=buf;
> mas_int[j]=(a[i]-48)*16+(a[i+1]-48);
> printf ("%x\n", mas_int[j]);
> i=i+2;
> j++;
> };
>}А где здесь sprintf или snprintf? Где массив int [4], который требовалось получить?
И, кстати, если уж речь когда-то зашла о sprintf, то эта функция запихивает данные в строку, но не наоборот. Наоборот делает, например, strtol. Но есть одна особенность - strtol преобразовывает строку в число, но требует, чтобы последний символ был не числом, а для выполнения задания это не подоходило.
>А где здесь sprintf или snprintf? Где массив int [4], который требовалось
>получить?
>И, кстати, если уж речь когда-то зашла о sprintf, то эта функция
>запихивает данные в строку, но не наоборот. Наоборот делает, например, strtol.
>Но есть одна особенность - strtol преобразовывает строку в число, но
>требует, чтобы последний символ был не числом, а для выполнения задания
>это не подоходило.mas_int[] - массив, а преобразуем ручками - mas_int[j]=(a[i]-48)*16+(a[i+1]-48);
а принт там вообще не требовался, эт так для проверки
> char buf,a[]="1234567890";А вот так лучше никогда не делай.
Иначе твоя прога получит от системы по морде 11-м сигналом, и потом можно долго думать из-за чего. Или явно выделяй память через malloc, или используй массив фиксированного размера, или вызывай strdup, типа char *a = strdup("1234567890");
Ну и я тоже свои 5 копеек вставлю :)#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main()
{
int i, num;
unsigned char *buf = strdup("1234567890");
unsigned short *b;fprintf(stderr,"%s\n", buf);
num = strlen(buf);
for(i = 0; i < num; i+=2) {
b = (unsigned short *)(buf+i);
asm("rolw $8, %1":"=r"(*b):"r"(*b));
}fprintf(stderr,"%s\n", buf);
return 0;
}
А вообще, зачем навороты с перестановкой в массиве? Ведь байты уже упорядочены.
Все можно переписать проще:#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main()
{
int i, num, n;
unsigned char *buf = strdup("1234567890");
unsigned int *m;fprintf(stderr,"%s\n", buf);
num = strlen(buf);
m = (unsigned int *)calloc(sizeof(unsigned int), num);
for(i = 0, n = 0; i < num; i+=2, n++)
m[n] = ((buf[i] & 0x0f) | ((buf[i+1] & 0x0f) << 4));for(i = 0; i < n; i++)
fprintf(stderr,"%.2x ", m[i]);fprintf(stderr,"\n");
return 0;
}
>А вообще, зачем навороты с перестановкой в массиве? Ведь байты уже упорядочены.
>
ну, так по условию задачи то надо получить ДВА массива - один с переставленными данными, а другой со значениями в HEX.
>Ну и я тоже свои 5 копеек вставлю :)
>
>#include <stdio.h>
>#include <stdlib.h>
>#include <string.h>
>
>int main()
>{
> int i, num;
> unsigned char *buf = strdup("1234567890");
> unsigned short *b;
>
> fprintf(stderr,"%s\n", buf);
>
> num = strlen(buf);
> for(i = 0; i < num; i+=2) {
> b = (unsigned short *)(buf+i);
> asm("rolw $8, %1":"=r"(*b):"r"(*b));
> }
>
> fprintf(stderr,"%s\n", buf);
> return 0;
>}ну и где free() для buf ? :)
strdup() тут нафик не нужен :)
>> char buf,a[]="1234567890";
>
>А вот так лучше никогда не делай.
>Иначе твоя прога получит от системы по морде 11-м сигналом, и потом
>можно долго думать из-за чего. Или явно выделяй память через malloc,
>или используй массив фиксированного размера, или вызывай strdup, типа char *a
>= strdup("1234567890");Бред.
>>> char buf,a[]="1234567890";
>>
>>А вот так лучше никогда не делай.
>>Иначе твоя прога получит от системы по морде 11-м сигналом, и потом
>>можно долго думать из-за чего. Или явно выделяй память через malloc,
>>или используй массив фиксированного размера, или вызывай strdup, типа char *a
>>= strdup("1234567890");
>
>Бред.
Хозяин барин
>> char buf,a[]="1234567890";
>
>А вот так лучше никогда не делай.
>Иначе твоя прога получит от системы по морде 11-м сигналом, и потом
>можно долго думать из-за чего. Или явно выделяй память через malloc,
>или используй массив фиксированного размера, или вызывай strdup, типа char *a
>= strdup("1234567890");чи?
Кернигана-Ритчи в утиль чтоли?
всю жисть инициализатор фиксированного размера делал массив фиксированым. с каким это компайлером вы -11 получите из этого кода?
или вы инициализатор и оператор присвоения путаете?\^P^/
>чи?
>Кернигана-Ритчи в утиль чтоли?
>всю жисть инициализатор фиксированного размера делал массив фиксированым. с каким это компайлером
>вы -11 получите из этого кода?
>или вы инициализатор и оператор присвоения путаете?
>
>\^P^/
Если б не получал - не говорил бы такого. Компиляторы - gcc 3.4.6, 4.1.1, и даже VC6.0/2005.
>
>>чи?
>>Кернигана-Ритчи в утиль чтоли?
>>всю жисть инициализатор фиксированного размера делал массив фиксированым. с каким это компайлером
>>вы -11 получите из этого кода?
>>или вы инициализатор и оператор присвоения путаете?
>>
>>\^P^/
>
>
>Если б не получал - не говорил бы такого. Компиляторы - gcc
>3.4.6, 4.1.1, и даже VC6.0/2005.А если получаешь, то тебе нужно быть внимательнее.
Работа с динамической памятью тут ни к чему.
>
>>чи?
>>Кернигана-Ритчи в утиль чтоли?
>>всю жисть инициализатор фиксированного размера делал массив фиксированым. с каким это компайлером
>>вы -11 получите из этого кода?
>>или вы инициализатор и оператор присвоения путаете?
>>
>>\^P^/
>
>
>Если б не получал - не говорил бы такого. Компиляторы - gcc
>3.4.6, 4.1.1, и даже VC6.0/2005.Пример в студию
Парни, был неправ, вспылил.Смотрите.
Например, если сделать так:char *a="123456";
a[3]='!';однозначно вылетаю по segfault, а если:
char a[]="123456";
a[3]='!';то все работает.
Воистину, век живи - век лечись.
>Парни, был неправ, вспылил.
Бывает..еще 2 копейки
>
>Смотрите.
>Например, если сделать так:
>
> char *a="123456";
> a[3]='!';
>
>однозначно вылетаю по segfault, а если:
еще бы, две ошибки сразу - сначала указатель без const на константную строку, а потом попытка поменять значение в ней ;)
const char *a = "123456"; //вот так правильно и дальше компилятора ошибка не пройдет если не делать грязных хаков>
> char a[]="123456";
> a[3]='!';
>
>то все работает.
ага, обязано работать т.к. a[] это уже массив содержимое которого можно менять.
>>Парни, был неправ, вспылил.
>Бывает..
>
>еще 2 копейки
>
>>
>>Смотрите.
>>Например, если сделать так:
>>
>> char *a="123456";
>> a[3]='!';
>>
>>однозначно вылетаю по segfault, а если:
>еще бы, две ошибки сразу - сначала указатель без const на константную
>строку, а потом попытка поменять значение в ней ;)
>const char *a = "123456"; //вот так правильно и дальше компилятора
>ошибка не пройдет если не делать грязных хаков
>
>>
>> char a[]="123456";
>> a[3]='!';
>>
>>то все работает.
>ага, обязано работать т.к. a[] это уже массив содержимое которого можно менять.
>
Все, разрулили.
Всем спасибо за поддержку и понимание :)
#include <stdlib.h>
#include <stdio.h>
/* правильное решение, но есть тонкость, зависищая от архитектуры */
char *digits="12345678";
int main() {
unsigned long b;
b=strtoul(digits,NULL,16);
printf("Word %llx\n",((b<<4)&0xf0f0f0f0ul)|((b>>4)&0x0f0f0f0ful));
return 0;
}
>#include <stdlib.h>
>#include <stdio.h>
>/* правильное решение, но есть тонкость, зависищая от архитектуры */
>char *digits="12345678";
>int main() {
> unsigned long b;
> b=strtoul(digits,NULL,16);
> printf("Word %llx\n",((b<<4)&0xf0f0f0f0ul)|((b>>4)&0x0f0f0f0ful));
> return 0;
>}
Хм, а ты проверял? Нетот результат то, нетот. И где массив? Понятно, немного доделать, но....
>#include <stdlib.h>
>#include <stdio.h>
>/* правильное решение, но есть тонкость, зависищая от архитектуры */
>char *digits="12345678";
>int main() {
> unsigned long b;
> b=strtoul(digits,NULL,16);
> printf("Word %llx\n",((b<<4)&0xf0f0f0f0ul)|((b>>4)&0x0f0f0f0ful));
> return 0;
>}
Все это дело печатает
Word 1021436587
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>char a[]="12345678";
void main()
{char *b = (char*) malloc(strlen(a)+1);
swab(a, b, strlen(a));
b[strlen(a)] = '\0';
printf("0x%x, 0x%x\n", atol(a), atol(b));
/* free(b); */
}
>#include <unistd.h>
[...]
> swab(a, b, strlen(a));К слову, swab(3) в Линукс ещё требует #define _XOPEN_SOURCE перед подключением файла unistd.h