Как вывести unsigned char
Есть массив типа unsigned char*. Можно ли его передать в функцию, требующую char*?
Что-то типа того:
void WriteToFile(unsigned char* msg, unsigned long count) < std::ofstream file("000.txt", std::ios::out|std::ios::binary); file.write((char*)&msg,count); file.close(); >
При попытке затем считать этот массив я получаю неверный массив:
void ReadFile() < ifstream file("000.txt", ifstream::in | ifstream::binary); // откроем файл file.seekg(0, ifstream::end); // перемотаем файл в конец, чтобы в (*) узнать размер unsigned long size = file.tellg(); vectorchar> data(size); // (*) создадим вектор размером с файл file.seekg(0, ifstream::beg); // перемотаем файл обратно на начало file.read(&data[0], size); unsigned char* msg = (unsigned char*)&data[0]; // . Это не исходный массив. file.close(); >
1. Можно ли массив типа unsigned char* передать в функцию, требующую char*? И наоборот?
2. Как преобразовать массив типа unsigned char* в массив типа char*. И наоборот?
Заранее огромное спасибо.
Re: Преобразовать массив типа unsigned char* в массив типа c
| От: | Bell | |
| Дата: | 06.09.05 11:36 | |
| Оценка: | +1 | |
Здравствуйте, Аноним, Вы писали:
А>Есть массив типа unsigned char*. Можно ли его передать в функцию, требующую char*?
А>Что-то типа того:
А>
А>void WriteToFile(unsigned char* msg, unsigned long count) А> < А>std::ofstream file("000.txt", std::ios::out|std::ios::binary); А> file.write((char*)&msg,count); А> file.close(); А>> А>
Амперсанд не нужен. С ним берется адрес локальной переменной, и соответственно в файл пришется совсем не то.
А>Вопрос
А>1. Можно ли массив типа unsigned char* передать в функцию, требующую char*? И наоборот?
Можно, см. ниже.
А>2. Как преобразовать массив типа unsigned char* в массив типа char*. И наоборот?
unsigned char* ptr = 0; char* ptr2 = reinterpret_castchar*>(ptr);
ЗЫ
ответственность за reinterpret_cast полностью на тебе.
Любите книгу — источник знаний (с) М.Горький
Re[2]: Преобразовать массив типа unsigned char* в массив тип
| От: | Аноним |
| Дата: | 06.09.05 12:03 |
| Оценка: |
Здравствуйте, Bell, Вы писали:
A>>
А>>void WriteToFile(unsigned char* msg, unsigned long count) А>>< А>> std::ofstream file("000.txt", std::ios::out|std::ios::binary); А>> file.write((char*)&msg,count); А>> file.close(); А>>> А>>
B>Амперсанд не нужен. С ним берется адрес локальной переменной, и соответственно в файл пришется совсем не то.
Крута! Теперь в файл пишется действительно осмысленный текст! Спасибо!
Но, вот считать правильно этот файл обратно в unsigned char* не получается
Re[3]: Преобразовать массив типа unsigned char* в массив тип
| От: | Bell |
| Дата: | 06.09.05 12:09 |
| Оценка: |
Здравствуйте, Аноним, Вы писали:
А>Крута! Теперь в файл пишется действительно осмысленный текст! Спасибо!
На здоровье
А>Но, вот считать правильно этот файл обратно в unsigned char* не получается
Ты это небось заключил на основании созерцания того, что показывает отладчик?
Любите книгу — источник знаний (с) М.Горький
Re[4]: Преобразовать массив типа unsigned char* в массив тип
| От: | Аноним |
| Дата: | 07.09.05 04:29 |
| Оценка: |
Здравствуйте, Bell, Вы писали:
А>>Но, вот считать правильно этот файл обратно в unsigned char* не получается
B>Ты это небось заключил на основании созерцания того, что показывает отладчик?
У меня есть функция, которая возвращает(создает) unsigned char* и функция, которая обрабатывает unsigned char*. Если они работают через память, т.е. я просто передаю массив созданный первой функцией во вторую, все хорошо.
Возникла необходимость в промежуточной обработке данного массива, причем данная функция принимает в качестве параметра просто char*. И я ничего поделать не могу, т.к. доступа к этой функции нет. Т.е. нужно преобразование unsigned char* -> char*. И наоборот.
Чтобы было проще, я сначала попытался выводить данный массив (unsigned char*) в файл, а потом считывать его с исрользованием функций, принимающих в качестве параметра char*. Когда будет понятно, что это работает, сделаю подобное преобразование через память.
Т.е. вывести в файл с вашей помощью получилось:
void WriteToFile(unsigned char* msg, unsigned long count) < std::ofstream file("000.txt", std::ios::out|std::ios::binary); file.write((char*)msg,count); file.close(); >
Преобразовать же считанный файл в unsigned char* не получается:
void ReadFile() < ifstream file("000.txt", ifstream::in | ifstream::binary); file.seekg(0, ifstream::end); // перемотаем файл в конец, чтобы в (*) узнать размер unsigned long size = file.tellg(); vectorchar> data(size); // (*) создадим вектор размером с файл file.seekg(0, ifstream::beg); // перемотаем файл обратно на начало file.read(&data[0], size); ofstream o("111.txt", ios::out | ios::binary); // Выводится считанный файл, т.е. считал я типа правильно o.write(&data[0], size); o.close(); //unsigned char* msg = (unsigned char*)&data[0]; unsigned char* msg = reinterpret_castchar*>(&data[0]); // Исходный массив не получается // дальнейшая обработка file.close(); >
Ошибка? Или особенность той функции, которая обрабатывает unsigned char*? Профессионалы, подскажите, плиз.
Заранее огромное спасибо!
Re[5]: Преобразовать массив типа unsigned char* в массив тип
| От: | Аноним |
| Дата: | 07.09.05 04:36 |
| Оценка: |
А>void ReadFile() А> < А>ifstream file("000.txt", ifstream::in | ifstream::binary); А> file.seekg(0, ifstream::end); // перемотаем файл в конец, чтобы в (*) узнать размер А> unsigned long size = file.tellg(); А> vectorchar> data(size); // (*) создадим вектор размером с файл А> file.seekg(0, ifstream::beg); // перемотаем файл обратно на начало А> file.read(&data[0], size); А> ofstream o("111.txt", ios::out | ios::binary); // Выводится считанный файл, т.е. считал я типа правильно А> o.write(&data[0], size); А> o.close(); А> //unsigned char* msg = (unsigned char*)&data[0]; А> unsigned char* msg = reinterpret_castchar*>(&data[0]); // Исходный массив не получается А> // дальнейшая обработка А> file.close(); А>> А>
А>Ошибка? Или особенность той функции, которая обрабатывает unsigned char*? Профессионалы, подскажите, плиз.
А>Заранее огромное спасибо!
Млин, если полученный массив опять вывести в файл, то все хорошо:
void ReadFile()
ifstream file(«000.txt», ifstream::in | ifstream::binary);
file.seekg(0, ifstream::end); // перемотаем файл в конец, чтобы в (*) узнать размер
unsigned long size = file.tellg();
vector data(size); // (*) создадим вектор размером с файл
file.seekg(0, ifstream::beg); // перемотаем файл обратно на начало
file.read(&data[0], size);
ofstream o(«111.txt», ios::out | ios::binary); // Выводится считанный файл, т.е. считал я типа правильно
o.write(&data[0], size);
o.close();
//unsigned char* msg = (unsigned char*)&data[0];
unsigned char* msg = reinterpret_cast(&data[0]); // Исходный массив не получается
Ничего не понимаю!
Re: Преобразовать массив типа unsigned char* в массив типа c
| От: | gear nuke | |
| Дата: | 07.09.05 17:18 | |
| Оценка: | +1 | |
Здравствуйте, <Аноним>, Вы писали:
А>Есть массив типа unsigned char*. Можно ли его передать в функцию, требующую char*?
Аноним>
char при хранении в памяти ничем не отличается от unsigned char и signed char.
Разница будет при операциях, учитывающих знак.
То есть, если «функция, требующуя char*» эти char’ы куда-то копирует (печатает, . ), то разницы не будет.
Если она считает их сумму (что для char недопустимо) — то может будет, а может и нет. Зависит от реализации.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Как выводить по 4 байта в строке unsigned char
как мне из неё циклом вывести по четыре элемента? Я не могу воспользоваться substr так как это unsigned char .
Отслеживать
68k 218 218 золотых знаков 79 79 серебряных знаков 221 221 бронзовый знак
задан 29 сен 2020 в 0:37
ResponseToMe ResponseToMe
57 3 3 бронзовых знака
4 ответа 4
Сортировка: Сброс на вариант по умолчанию
Да выводить по одному символу, а каждые 4 — перевод строки:
unsigned char t[] = "valera123456789"; for(int i = 0; t[i]; ++i)
Отслеживать
ответ дан 29 сен 2020 в 3:59
219k 15 15 золотых знаков 119 119 серебряных знаков 230 230 бронзовых знаков
Можно использовать старый добрый printf с указанием размера строки.
#include int main() < unsigned char t[] = "valera123456789"; for(auto p = t; p < sizeof(t) + t; p += 4) < std::printf("%.4s\n", p); >>
Отслеживать
ответ дан 29 сен 2020 в 7:20
28.8k 12 12 золотых знаков 59 59 серебряных знаков 118 118 бронзовых знаков
Во-первых, объявление unsigned char[16] t = «valera123456789» некорректно.
Во-вторых, вот решение:
#include #include int main() < unsigned char t[16] = "valera123456789"; for (int i = 0; i < strlen((char*)t); i += 4) < char copy[5]; strncpy(copy, (char *) t + i, 4); copy[4] = 0; printf("%s\n", copy); >getchar(); return 0; >
Это решение не адаптировано для различных размеров строк и выводимых подстрок. Надеюсь, разберётесь, в каких местах нужно заменить числовые константы на переменные, чтобы добавить универсальности. Ключевые моменты:
- Чтобы скопировать определённое кол-во символов из одной строки в другую, необходимо использовать strncpy(указатель на строку-приёмник, указатель на строку источник, кол-во символов) . При этом следует обратить внимание, что указатель может указывать не только на начало строки, но и на любой символ, начиная с которого необходимо производить копирование. В моём примере, чтобы скопировать символы, начиная, например, с 4-ого, я просто сдвигал указатель обычным сложением ( t + i ).
- Также очень важно в конце копии поставить нуль-символ ( 0 или ‘\0’ ): copy[4] = 0; , т.к. в противном случае строка-копия будет некорректно распознана функцией вывода (появятся лишние символы в конце).
Как вывести unsigned char
Добрый день!
Занимаюсь целочисленным программированием и по этой причине часто использую целые типы данных.
С основными целочисленными типами данных работается легко и без проблем: short, int, long long int. (и соответствующие unsigned).
Но вот есть в C/C++ загадочный целочисленный тип данных: char
С ним-то и возникают проблемы.
При попытке его использования (работа с целыми числами от -128 до 127) все программы работают правильно, но компиляторы (особенно современные) выдают просто россыпь предупреждений:
warning: array subscript has type ‘char’ [-Wchar-subscripts]
Например, в небольшой программе решения Задачи Коммивояжера методом динамического программирования мне выдается 52 (. ) предупреждения!
Как я понял, проблема довольно фундаментальная.
Даже при чтении/выводе на консоль целых переменных типа char не существует специального модификатора.
Приходится с printf/scanf использовать %hhd. И тоже с предупреждениями.
Вопрос: какой прием надо использовать для целочисленных переменных типа char, чтобы избавиться от этих бесконечных предупреждений?
Может ключ какой-то надо указать компилятору?
P.S. 1. Зачем все это? Просто переменная типа char занимает 1 байт, а уже переменная типа short — аж 2 байта. Для некоторых задач целочисленного программирования эта экономия существенна!
(В Паскале все было проще — там byte и char разные типы данных).
2. Все те же вопросы актуальны и для типа unsigned char.
3. Наверное, этой теме уже лет 60 — ровно столько, сколько существует язык Си. И она давно уже разжевана.
Тогда просьба — дайте ссылку на статью, где все это объясняется покороче и «на пальцах».
Функция printf
Для вывода данных в языке C используется функция printf . Для использования этой функции необходимо подключить заголовочный файл stdio.h :
Если вы пишете на C++, то лучше подключать файл cstdio :
Функция printf получает один или более аргументов. Первый аргумент — строка, которую нужно вывести. Например, если нужно просто вывести какой-то текст, то можно написать так:
Символ ‘\n’ в конце вывода означает символ перехода на новую строку.
Если нужно вывести значения какой-то переменной, то в форматной строке вместо этой переменной указывается специальное выражение, начинающееся с символа «%». Например, для вывода целого числа типа int указывается строка «%d». Сами переменные указываются после форматной строки, следующими параметрами, передаваемыми функции printf .
Например, чтобы напечатать значения переменных a и b типа int через пробел можно использовать следующую функцию:
Выводимые типы
Перечислим разные типы данных, которые можно выводить при помощи функции printf и соответствующие им форматные строки.
| %d или %i |
Выводится целое число (значение типа int) в десятичной системе счисления. Для вывода значений типа short int используется %hd, long int — %ld, long long int — %lld. |
| %u | Выводится беззнаковое целое число (значение типа unsigned int) в десятичной системе счисления. Для вывода значений типа unsigned short используется %hu, unsigned long — %lu, unsigned long long — %llu. |
| %e | Выводится значение типа double в экспоненциальной форме, например, число 123.456 будет выведено в виде 1.234560e+002. Для вывода значения типа double также используется %le, для вывода long double — %Le (в Windows может не работать). |
| %f | Выводится значение типа double с фиксированной точкой. Например, число 1e20 будет выведено, как 10000000000.000000. Для вывода значения типа double также используется %lf, для вывода long double — %Lf (в Windows может не работать). |
| %g | Значение типа double выводится либо с фиксированной точкой, либо с плавающей точкой, в зависимости от величины числа. Аналогично используется %lg для double и %Lg для long double. |
| %c | Выводится один символ (значение типа char). |
| s | выводится содержимое C-строки. В качестве параметра передается указатель char * или массив символов char[]. |
| %% | Вывести один символ %, никакого значения переменной при этом не передается. |
Значения целых чисел также можно выводить в восьмеричной или шестнадцатеричной системах счисления.
Обратите внимание, переменную типа float вывести при помощи функции printf нельзя (можно привести значение типа float к типу double и вывести его).
В операционной системе Windows не рекомендуется использовать тип long double.
Модификаторы длины
Эти модификаторы пишутся между знаком % и символом, обозначающим тип. Например, %lld. Эти модификаторы используются для того, чтобы вывести значения типов short int, long int , long double и т.д. и уже упоминались раньше.
Используется для значения типа long int или unsigned long int вместе с модификаторами d, i, u.
Используется для значения типа double вместе с модификаторами e, f, g.
Ширина поля вывода
После знака % можно задать ширину поля для вывода в виде целого числа (не начинающегося с нуля). В этом случае число вывод этого числа будет занимать указанное число символов. Если в числе меньше цифр, чем заданная ширина поля вывода, то перед числом (слева) выводятся пробелы. Если же в числе больше цифр, чем ширина поля, то выводятся все цифры (то есть выводится больше цифр, чем вся ширина поля, поле расширяется, чтобы вывести все символы).
Если перед шириной поля поставить цифру 0, например, «%010d», то число будет дополняться слева не пробелами, а нулями. Это удобно, например, для вывода времени в формате hh:mm, что можно сделать, например, так:
printf(«%02d:%02d», h, m);
Если перед шириной поля поставить знак «-«, то число будет дополняться пробелами не слева, а справа (сначала выводится число, потом — дополнительные пробелы до заполнения всего поля).
Также вместо ширины поля вывода можно указать символ «*» (звездочка), тогда значение ширины поля вывода нужно передать в качестве дополнительного параметра. Например, запись:
означает вывести значение переменной a используя поле шириной n символов.
Точность вывода действительных чисел
По умолчанию действительные числа выводятся с 6 знаками после точки, при этом числа в экспоненциальной форме выводятся в виде одной цифры, точки и 6 цифр после точки (и показателя степени).
Для изменения точности вывода действительных чисел в форматной строке указывается символ точки (‘.’) и после нее число — количество выводимых знаков после точки. Например, так:
Вывод целых чисел со знаком +/-
Если при выводе целого числа в форматной строке задать символ «+», то положительные числа будут выводиться с обязательным знаком «+» перед ними.
Большинство перечисленных выше параметров комбинируются друг с другом. Например, такая строка:
означает вывод числа типа long long, со знаком «+» или «-» перед числом, с добавлением нулей таким образом, что общее число выводимых символов будет не меньше 20.