Russian Qt Forum
Сентябрь 30, 2024, 10:30 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Смена мест байтов в QByteArray  (Прочитано 8842 раз)
blackalegator
Гость
« : Май 25, 2013, 03:27 »

Тренируюсь в c++/Qt. (Перехожу с явы) Дается все нелегко, ссылки, указатели и тп заставляют периодически рвать волосы на своей голове. В качестве упражнения решил написать функцию для смены мест байтов в QByteArray. Вот к чему пришел:
Код:
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);

        QString t = "abcde";
        QByteArray test= t.toLatin1();

        qDebug() << test;
        qDebug() << QString(swapBytes(test,0,3));

        return a.exec();
    }

    QByteArray swapBytes(QByteArray in, int swapOffset, int quantity) {
        if (swapOffset < 0) {
            return in;
        }
        if(quantity>(in.length()/2)) {quantity=in.length()/2;}
        if(quantity < 1) {quantity=1;}
        int k;
        char buf[quantity];
        char buf2[quantity];
        memset(buf, 'z', quantity); memset(buf2, 'z', quantity);
        qDebug() << quantity;
        for (int i = 0; i + quantity*2 + swapOffset <= in.length(); i=i+2*quantity) {
            k=i;
            for(int b = 0;b<quantity;b++){
                buf[b]=in.at(k);
                buf2[b]=in.at(k+swapOffset+quantity);
                k++;
            }
            qDebug() << buf;
            qDebug() << sizeof(buf);
            qDebug() << (int)buf[1];
            qDebug() << buf2;
            qDebug() << in;
            in.replace(i,quantity,buf2);
            qDebug() << in;
            in.replace(i+quantity+swapOffset,quantity,buf);
        }
        return in;
    }
}

К сожалению по неизвестной причине у меня на выходе выводиться
abcde
ab(
cd
abcde
cdcde
cdab(e

Я не понимаю откуда вываливается эта скобка. Так же, если поменять входной массив на
« Последнее редактирование: Май 25, 2013, 13:37 от blackalegator » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Май 25, 2013, 10:01 »

Непонятно что Вы хотите получить. Напр 20 элементов, swapOffset = 2, quantity = 4. Какой результат ожидается?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #2 : Май 25, 2013, 10:07 »

Тренируюсь в c++/Qt.
Нужно вначале натренироваться с C++, а потом подходить к Qt.

(Откуда там бесконечный цикл я не понимаю)
Нужно уже знать, что такое:
Код
C++ (Qt)
char buf[ len ];
и как к этому относиться qDebug(), тогда станет понятно почему он не останавливается при выводе.
Записан
Странник
Гость
« Ответ #3 : Май 25, 2013, 10:33 »

На stackoverflow предложили инициализировать buf и buf1. Не помогло
и правильно предложили, нуль-терминированные же строки. в приведенном коде инициализации нет.
кроме того, buf и buf2 у вас размера quantity (забыли зарезервировать символ под нуль-терминатор), при этом в цикле они заполняются и вовсе до i+quantity - выход за границы массива просто по всем фронтам.
Записан
blackalegator
Гость
« Ответ #4 : Май 25, 2013, 13:46 »

Я изменил код. (В главном посте новый) Писал глубокой ночью, поэтому и написал i+quantity. С длинными строками все работает, но пример с abcde не работает опять. Появляется скобочка. После этого решил вывести в qDebug() << buf[2] и вылезла та самая скобочка. Почитал описание replace и вот что нашел:

QByteArray & QByteArray::replace(int pos, int len, const char * after)
This is an overloaded function.

Replaces len bytes from index position pos with the zero terminated string after.

Notice: this can change the length of the byte array

Довольно странно. По идее она должна была заменить только 2 байта
(У меня было in.replace(i+quantity+swapOffset,quantity,buf);
Однако она меняла 3. Поменял ее на in.replace(i+quantity+swapOffset,quantity,buf,quantity);
И все полностью заработало.

Заодно узнал, что в с++ выход за границы массива не останавливает программу, как в Java. Спасибо всем мне помогавшим
Записан
blackalegator
Гость
« Ответ #5 : Май 25, 2013, 15:54 »

На stackoverflow предложили инициализировать buf и buf1. Не помогло
и правильно предложили, нуль-терминированные же строки. в приведенном коде инициализации нет.
кроме того, buf и buf2 у вас размера quantity (забыли зарезервировать символ под нуль-терминатор), при этом в цикле они заполняются и вовсе до i+quantity - выход за границы массива просто по всем фронтам.

Нуль-терминатор? Прямо страшно становиться. Что это такое?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Май 25, 2013, 16:15 »

Чувствуется кладка "жабиста"  Улыбающийся К слову
Код:
    QByteArray swapBytes(QByteArray in, ...
Хотя это приемлемо в Qt, с точки зрения языка - говнокод. Такое ускорять хорошо (раз так в 5-10)  Улыбающийся
Записан
Странник
Гость
« Ответ #7 : Май 26, 2013, 10:15 »

Нуль-терминатор? Прямо страшно становиться. Что это такое?
Нуль-терминатор - символ '\0' (с кодом 0). он считается символом завершения строки. если при передаче строки в функцию вы не указываете ее длину явно, строкой считается все от начала до первого вхождения нуль-терминатора. если же ваша строка нуль-терминатора не содержит, происходит выход за границы.
Речь идет о С-строках, разумеется.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #8 : Май 26, 2013, 21:05 »

Хотя это приемлемо в Qt, с точки зрения языка - говнокод. Такое ускорять хорошо (раз так в 5-10)  Улыбающийся

Што? Это является узким местом?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Май 27, 2013, 11:29 »

Што? Это является узким местом?
Да, если имплисит шара не подотрет сопли, напр
Код:
std::vector swapBytes(std::vector in, ...
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #10 : Май 29, 2013, 17:38 »

еще лучше передавать ссылку, быстрее будет вызов процедуры происходить, почитайте про передачу/возврат параметров в функции с++...
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #11 : Май 29, 2013, 23:06 »

Што? Это является узким местом?
Да, если имплисит шара не подотрет сопли, напр
Код:
std::vector swapBytes(std::vector in, ...

Вы же прекрасно понимаете, что ботлнеком оно станет только при 100500 вызовах, а у автора-это не так.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Май 30, 2013, 08:56 »

Вы же прекрасно понимаете, что ботлнеком оно станет только при 100500 вызовах, а у автора-это не так.
А зачем разбираться "так или не так" - гораздо проще всегда подавать приличные структуры по ссылке или указателю
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #13 : Май 30, 2013, 11:07 »

Вы же прекрасно понимаете, что ботлнеком оно станет только при 100500 вызовах, а у автора-это не так.
А зачем разбираться "так или не так" - гораздо проще всегда подавать приличные структуры по ссылке или указателю

Затем, что разбираться всё равно придётся - сказать навскидку, где ботлнек в программе, сложно. А, экономя на спичках, вы только себе жизнь усложняете (я про тот случай, когда оптимизация ухудшает читаемость\простоту использования кода).
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Май 30, 2013, 11:13 »

Затем, что разбираться всё равно придётся - сказать навскидку, где ботлнек в программе, сложно. А, экономя на спичках, вы только себе жизнь усложняете (я про тот случай, когда оптимизация ухудшает читаемость\простоту использования кода).
Код
C++ (Qt)
void MyFunc( const Container & c  ...)  // это не вызывает никаких вопросов
void MyFunc( Container c  ...)   // а что это ?? Так задумано, или описАлся ??
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.222 секунд. Запросов: 23.