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

Перевести строку в 16-й формат - C++

Восстановить пароль Регистрация
 
 
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
22.11.2015, 20:33     Перевести строку в 16-й формат #1
Нужно перевести строку(string) в 16-й формат, как сделать? Знаю про std:hex, но он работает только с char и записать получаемое число в другую переменную нельзя.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Minchanin-Bel
5 / 5 / 1
Регистрация: 19.09.2010
Сообщений: 167
22.11.2015, 20:45     Перевести строку в 16-й формат #2
C++
1
2
std::string s = "5f0066";
int num = std::stoi(s, 0, 16);
Добавлено через 6 минут
Для вывода:
C++
1
std::cout << std::hex << num;
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
22.11.2015, 20:49  [ТС]     Перевести строку в 16-й формат #3
А можно это реализовывать с файловым вводом/выводом?
Данный код не работает, останавливает работу и выдает ошибку Возникло необработанное исключение по адресу 0x7584C42D в ТЕСТ.exe: исключение Microsoft C++: std::invalid_argument по адресу памяти 0x0030F9F4.
Код:
C++
1
2
3
4
5
6
7
8
string input;
    string str;
    ifstream f("C:\\EXE.exe");
    while (!f.eof()) {
        getline(f, input);
        str += input;
    }
    stoi(str, 0, 16);
Добавлено через 57 секунд
Упс, не заметил второе сообщение. Сейчас

Добавлено через 52 секунды
Хотя выдает такую же ошибку, которую описал выше
Minchanin-Bel
5 / 5 / 1
Регистрация: 19.09.2010
Сообщений: 167
22.11.2015, 21:09     Перевести строку в 16-й формат #4
C++
1
2
3
4
5
6
7
8
9
10
std::ofstream fileOut("out.txt");
    std::ifstream fileIn("in.txt");
    std::string s = "5f0066";
    int num = std::stoi(s, 0, 16);
    fileOut << std::hex << num << std::endl;
    getline(fileIn, s);
    int numIn = stoi(s, 0, 16);
    std::cout << std::hex << numIn << std::endl;
    fileOut.close();
    fileIn.close();
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
22.11.2015, 21:18  [ТС]     Перевести строку в 16-й формат #5
А без записи в другой файл? Создавать файл, чтобы в него записать одну строчку, причем этот файл используется как буфер - это, мне кажется, не практично.
Нашел в интернете, но там выдает немного не правильный результат(сравнивал две получившиеся строки). Как это можно использовать, чтобы сделать верную ф-цию перевода.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string string_to_hex(const string& input)
{
    static const char* const lut = "0123456789ABCDEF";
    size_t len = input.length();
 
    string output;
    output.reserve(2 * len);
    for (size_t i = 0; i < len; ++i)
    {
        const unsigned char c = input[i];
        output.push_back(lut[c >> 4]);
        output.push_back(lut[c & 15]);
    }
    return output;
}
Minchanin-Bel
5 / 5 / 1
Регистрация: 19.09.2010
Сообщений: 167
22.11.2015, 21:24     Перевести строку в 16-й формат #6
Погодите, объясните понятнее задачу... Выше есть пример(продублирую тут) считывания числа в 16 формате в std::string, затем его перевод в int и вывод на консоль в 16 с/с. Какая задача-то..?

К примеру, в файле in.txt будет строка abc, которая считается в переменную s. Затем, в 4 строке, функция stoi переведет эту строку в int. В следующей строке вывод int в формате 16 с/с.

C++
1
2
3
4
5
6
    std::ifstream fileIn("in.txt");
    std::string s;
    getline(fileIn, s);
    int numIn = stoi(s, 0, 16);
    std::cout << std::hex << numIn << std::endl;
    fileIn.close();
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
22.11.2015, 21:43  [ТС]     Перевести строку в 16-й формат #7
Задача - нужно из файла считать строку в переменную типа string, пусть эта строка будет abc. Следовательно s = abc. Дальше нужно создать еще переменную типа string ы2 и записать в нее 16 - ричное значение s,то есть abc. Переменная s2 будет иметь такой вид(к примеру, не знаю, как abc будет выглядить в 16-й с/c) - 45a50f. Ну а дальше вывести на экран.
Minchanin-Bel
5 / 5 / 1
Регистрация: 19.09.2010
Сообщений: 167
22.11.2015, 21:56     Перевести строку в 16-й формат #8
Строка в файле - это шестнадцатеричное число или нет?
16 с/с содержит: 0123456789abcdef
Т.е. строка abc в файле будет представлена в num как 0x00000abc
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
22.11.2015, 22:03  [ТС]     Перевести строку в 16-й формат #9
Строка в файле - не число вообще. Это набор символов или букв. Например это - A string like "Hello World" to hex format: 48656C6C6F20576F726C64. Нашел на сайте. Слова типа Hello World будут в файле(ну или любые другие слова). Вообще, может я думаю не в правильном направлении. Мне надо вывести последовательность байт файла. Это из себя представляет 16-ричную строку, например - 48656C6C6F20576F726C64. Но обязательно все записывать в переменные типа string.
nmcf
4316 / 3737 / 1260
Регистрация: 14.04.2014
Сообщений: 14,664
22.11.2015, 23:51     Перевести строку в 16-й формат #10
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
string input;
    string str, str2;
    ifstream f("C:\\data.txt");
    while (!f.eof()) {
        getline(f, input);
        str += input;
    }
 
    ostringstream oss;
 
    for (int i = 0; i < str.length(); ++i)
        oss << setw(2) << setfill('0') << static_cast<unsigned>(static_cast<unsigned char>(str[i]));
 
    str2 = oss.str();
Minchanin-Bel
5 / 5 / 1
Регистрация: 19.09.2010
Сообщений: 167
23.11.2015, 08:54     Перевести строку в 16-й формат #11
Цитата Сообщение от nmcf Посмотреть сообщение
static_cast<unsigned>(static_cast<unsigned char>(str[i]))
При этом в выходной строке будут числа в 10 с/с, разве нет? ТС, как я понял, хочет, чтобы в выходной строке были числа в 16 с/с, т.е. ASCII коды символов в 16 с/с.
nmcf
4316 / 3737 / 1260
Регистрация: 14.04.2014
Сообщений: 14,664
23.11.2015, 09:52     Перевести строку в 16-й формат #12
Цитата Сообщение от Minchanin-Bel Посмотреть сообщение
При этом в выходной строке будут числа в 10 с/с
C++
1
oss << setw(2) << setfill('0') << hex << static_cast<unsigned>(static_cast<unsigned char>(str[i]));
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
23.11.2015, 18:53  [ТС]     Перевести строку в 16-й формат #13
То, что я прошу, по идее, должно вывести, как минимум, часть заголовка exe файла, так?. Вот, что из себя представляет этот заголовок:
00-01 4D5A — сигнатура файла .EXE;
02-03 Длина образа задачи по модулю 512 (то есть число полезных байт в последнем блоке). Компоновщики версий до 1.10 помещали в это поле 04; если оно имеет такое значение, его рекомендуется игнорировать);
04-05 Длина файла в блоках;
06-07 Число элементов таблицы настройки адресов;
08-09 Длина заголовка в 16-байтных параграфах. Используется для выяснения начала тела загрузочного модуля;
0A-0B Минимальный объем памяти, которую нужно выделить после конца образа задачи (в 16-байтных параграфах);
0C-0D Максимальный объем памяти, которую нужно выделить после конца образа задачи (в 16-байтных параграфах);
0E-0F Сегментный адрес начала стекового сегмента относительно начала образа задачи;
10-11 Значение SP при входе в задачу;
12-13 Контрольная сумма — ноль минус результат сложения без переноса всех слов файла;
14-15 Значение IP (счетчика команд) при входе в задачу;
16-17 Сегментный адрес начала кодового сегмента относительно начала образа задачи;
18-19 Адрес первого элемента таблицы настройки адресов относительно начала файла;
1A-1B Номер сегмента перекрытий (0 для корневого сегмента программы).

Добавлено через 4 минуты
Я плохо разбираюсь в exe. Я думаю, что заблуждаюсь в том, что надо выводить последовательность байт именно тем способ, что я прошу.
WhiteP
605 / 203 / 23
Регистрация: 20.11.2012
Сообщений: 419
23.11.2015, 19:41     Перевести строку в 16-й формат #14
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
#include <iostream>
#include "windows.h"
#include <fstream>
#include <iomanip>
 
int main(int argc, char ** argv)
{
    std::ifstream ifs("test.exe", std::ios::binary);
 
    PBYTE buf = new BYTE[512];
 
    ifs.read((char*)buf, 512);
    std::cout.fill('0');
    std::cout << "     ";
    for (int i = 0; i < 16; i++)
        std::cout << "  " << std::hex <<  std::setw(2)<< std::uppercase << i;
    std::cout << '\n' << std::endl;
 
 
    for (int i = 0; i < 512; i+=16)
    {
        std::cout << std::hex << std::setw(3) << std::uppercase << i << "  ";
        for (int c = 0; c < 16; c++)
        {
            std::cout << "  " << std::hex << std::setw(2) << std::uppercase <<(int) buf[i+c];
        }
        std::cout << std::endl;
    }
    system("pause");
    ifs.close();
 
 
}
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
23.11.2015, 19:56  [ТС]     Перевести строку в 16-й формат #15
Вооот, то что надо, спасибо огромное А не могли бы Вы пояснить все строчки кода, пожалуйста. Буду благодарен.

Добавлено через 10 минут
Совсем забыл. Еще нужно использовать переменные типа string, куда это добавить?

Добавлено через 1 минуту
Все усложняется из-за алгоритма поиска подстроки, который поддерживает только string
WhiteP
605 / 203 / 23
Регистрация: 20.11.2012
Сообщений: 419
23.11.2015, 20:04     Перевести строку в 16-й формат #16
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
46
#include <iostream>
#include "windows.h"
#include <fstream>
#include <iomanip>
 
int main(int argc, char ** argv)
{
    //открываем бинарный файл
    std::ifstream ifs("test.exe", std::ios::binary);
 
    //формируем буфер из 512 байт
    PBYTE buf = new BYTE[512];
 
    //читаем 512 байт в буфер
    ifs.read((char*)buf, 512);
 
    //заливка нулями (чтобы было 01, а не 1)
    std::cout.fill('0');
 
    //отступ для выравнивания таблицы
    std::cout << "     ";
 
    //шапка с номерами байт
    for (int i = 0; i < 16; i++)
        //вывод в 16м формате, прописными символами, шириной мин 2 символа (остальное заливается 0 (см. выше)
        std::cout << "  " << std::hex <<  std::setw(2)<< std::uppercase << i;
 
    //отступ
    std::cout << '\n' << std::endl;
 
    //выводим по 16 байт на строку
    for (int i = 0; i < 512; i+=16)
    {
        //номер строки
        std::cout << std::hex << std::setw(3) << std::uppercase << i << "  ";
        for (int c = 0; c < 16; c++)
        {
            //вывод потока байт в 16м формате, прописными символами, шириной мин 2 символа (остальное заливается 0 (см. выше)
            std::cout << "  " << std::hex << std::setw(2) << std::uppercase <<(int) buf[i+c];
        }
        std::cout << std::endl;
    }
    delete[] buf;
    system("pause");
    ifs.close();
}
А зачем string? Я C++ не помню уже, все больше неприплюснутый си и winapi, так что вот так сразу как в строку, а не в поток выводить - не скажу.
А вообще работа с потоком байт через string - это костыль тот еще, имхо.
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
24.11.2015, 16:35  [ТС]     Перевести строку в 16-й формат #17
Да вот, string обязателен, буду думать. Кстати, а это можно сделать через двумерный массив, ведь. Тоже самое, только у каждой ячейки будет свой номер. Пойду думать

Добавлено через 20 часов 21 минуту
Смотрите, я попробовал так записать в переменную байты, в консоли все выводится очень долго(связано с кол-вом повторений в цикле) , байты все идут и идут. Что может тут не правильно? Кстати и не совсем правильно выводит.
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
int main(int argc, char ** argv)
{
    //открываем бинарный файл
    std::ifstream ifs("C:\\exe.exe", std::ios::binary);
 
    //формируем буфер из 512 байт
    PBYTE buf = new BYTE[512];
 
    //читаем 512 байт в буфер
    ifs.read((char*)buf, 512);
    string str2;
 
    stringstream s;
 
        for (int i = 0; i < 128; i++)
        {
            s << setw(2) << setfill('0') << hex << (int)buf[i];
            str2 = s.str();
            cout << str2;
        }
 
    delete[] buf;
    system("pause");
    ifs.close();
}
nmcf
4316 / 3737 / 1260
Регистрация: 14.04.2014
Сообщений: 14,664
25.11.2015, 13:48     Перевести строку в 16-й формат #18
Nik-, это ты всё сигнатуры те делаешь? Зачем вообще преобразовывать бинарные данные в шестнадцатеричное текстовое представление? Просто посмотреть на них? Поиск последовательности байтов работает без всякого преобразования:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    std::ostringstream oss;
 
    std::ifstream ifs("c:\\exe.exe", std::ifstream::binary);
 
    oss << ifs.rdbuf();
 
    std::string data = oss.str(); // содержимое файла - в data
 
    ifs.close();
 
    char s[] = "\xC0\x2C\x00\x00\x10"; // последовательность, которую ищем: 0xC02C000010
    std::string ss;
    ss.resize(5);
    std::copy(s, s + 5, ss.begin()); // записать последовательность в string
 
    int p;
    if ((p = data.find(ss)) != std::string::npos)
        {
            // найдено в позиции p
        }
Nik-
19 / 19 / 9
Регистрация: 12.07.2015
Сообщений: 322
25.11.2015, 15:39  [ТС]     Перевести строку в 16-й формат #19
Да, эти сигнатуры мне еще долго делать, проектная работа. Попробовал найти обычную сигнатуру 4a5d, определяющую, что файл exe. Но так и ничего не нашел . Может что-то не понял?
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
#include <iostream>
#include <string>
#include <sstream>
#include<fstream>
using namespace std;
 
 
int main()
{
    std::ostringstream oss;
 
    std::ifstream ifs("C:\\exe.exe", std::ifstream::binary);
 
    oss << ifs.rdbuf();
 
    std::string data = oss.str(); // содержимое файла - в data
 
    ifs.close();
    char s[] = "\x4d\x5a";// последовательность, которую ищем: 0xC02C000010
    std::string ss;
    ss.resize(5);
    std::copy(s, s + 5, ss.begin()); // записать последовательность в string
 
    int p;
    if ((p = data.find(ss)) != std::string::npos)
    {
        // найдено в позиции p
        cout << "Yes" << endl;
    }
 
 
    system("PAUSE");
    return 0;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.11.2015, 17:26     Перевести строку в 16-й формат
Еще ссылки по теме:

Перевести длинную бинарную строку в строку с десятичными цифрами C++
Перевести 1 строку с С#на С++ C++
Как перевести строку в BSTR* C++

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

Или воспользуйтесь поиском по форуму:
nmcf
4316 / 3737 / 1260
Регистрация: 14.04.2014
Сообщений: 14,664
25.11.2015, 17:26     Перевести строку в 16-й формат #20
Надо же корректировать длину. У меня 5 байт, а у тебя 2:
C++
1
2
3
4
    char s[] = "\x4d\x5a";// последовательность, которую ищем
    std::string ss;
    ss.resize(2);
    std::copy(s, s + 2, ss.begin()); // записать последовательность в string
Yandex
Объявления
25.11.2015, 17:26     Перевести строку в 16-й формат
Ответ Создать тему
Опции темы

Текущее время: 15:20. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru