本文介绍了istreams没有setw?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 大家好, 我正在尝试将一些代码放在一起,从istream中读取3对相邻的十六进制 位数。每个十六进制数字对代表一个非负的 整数。 例如我想从01ff12中提取1,255和18(作为 我的应用程序中的简单RGB颜色的组件。 我希望找到类似std :: setw的istreams并使用它 与std :: hex结合使用,以便我可以在 时读取2个十六进制数字,但据我所知,C ++中不存在这样的实体 标准库。 有没有干净整洁的方式做我想做的事情,或者我要去 必须做一些令人讨厌的事情,比如把每个数字对在它自己的 缓冲区和流提取/ strtoul那里的数字? 为什么istreams不存在与setw相当的东西? Edd 解决方案 有很多方法可以接近这个问题,这不是最好的方式。 你可以计算机如何用十六进制字符对计数。 从std :: istringstream或std :: istream&中提取两个字符。是的,但是这会让你得到一个ascii翻译,而不是你需要的。 Hex类的const_char_array ctor需要3个字符,而不是2个字符(因为 null终止)。 cvt(...)函数将每个十六进制数字转换为无符号等价物 而ctor(s)init列表负责计算最终的 无符号结果。超出范围的任何十六进制数字都会产生 异常。 这应该是一个可移植的解决方案。但这还有待观察。 #include< iostream> #include< ostream> #include< ; string> #include< stdexcept> class Hex { char m_16c ; //左边的十六进制数字* 16 char m_c; //右十六进制数 unsigned m_n; //结果 public: Hex(const char(& array)[3])// ctor,char array [3] by ref :m_16c(array [0]),m_c(array [1]), m_n(16 * cvt(m_16c)+ cvt(m_c)){} Hex(std :: string& s)// ctor,一串2个字符,其他字符被忽略 :m_16c(s [0]),m_c(s [1]), m_n(16 * cvt(m_16c)+ cvt(m_c)){} Hex(const Hex& copy)// copy ctor { m_16c = copy.m_16c; m_c = copy.m_c; m_n = copy.m_n; } //成员函数 unsigned cvt(const char c)const { if(c> ; =''0''&& c< ='''9'') { 返回c - ''0''; }否则if(c> =''a''&& c< =''f'') { return 10 +(c - ''''); }否则if(c> =''A''&& c< =''F'') { 返回10 +(c - ''A''); }否则 { 抛出std :: runtime_error(Hex超出范围。); } } //朋友运营商 朋友std :: ostream& 运营商<<(std :: ostream& os,const Hex& r_h) { return os<< r_h.m_n; } }; int main() { 尝试{ //测试十六进制对 十六进制h255(" ff"); std :: cout << h255<< std :: endl; Hex h16(" 10"); std :: cout<< h16<< std :: endl; Hex h0A(" 0A"); std :: cout<< h0A<< std :: endl; //解析缓冲区 std :: string buffer(" ff100a"); std :: string red(buffer,0,2); // substr 十六进制r(红色); std :: cout<< r: << r<< std :: endl; std :: string green(buffer,2,2); Hex g(绿色); std: :cout<< g: << g<< std :: endl; std :: string blue(buffer,4,2); Hex b(蓝色); std: :cout<< b: << b<< std :: endl; } catch(std :: exception& r_e) { std: :cerr<< 错误: << r_e.what(); std :: cerr<< std :: endl; } } / * 255 16 10 r:255 g:16 b:10 * / 注意main()中的std :: string缓冲区如何被包围并加载到单个Hex变量中的。 想象一个带有3个十六进制成员(r,g和b)的Color类,适当的 ctors和操作符重载,甚至是文件读取器功能。 你可以打开一个使用std :: ifstream文件并使用std :: getline加载 ,一次缓冲一行。 [慷慨的代码剪辑] 非常感谢你的回复。我想出了一些同样长的东西 winded。我希望istreams可以提供一种方式来完成这个 ,因为任务似乎适合他们的工作描述。 其实我是不确定您的代码是否完全可移植。如果我不是错误的话,那么你认为你假设所有的字符集都有 具有连续值的字母字形(即他们可以做到 aAbBcCdD ......就我所知而言。 但它只是表明这样一个问题是多么狡猾。我需要将b字符剥离成两位数的 缓冲区并从中读取:/ 亲切问候, Edd 如何从流中读取所有六位数字作为一个数字, 使用std :: hex然后使用 模数运算? 这样可以省去两位数的缓冲区,但可能你会这样做/ b $ b会遇到小/大 - 期末问题。 HTH, - J. Hello all,I''m trying to put together some code that reads 3 adjacent pairs of hexdigits from an istream. Each hex digit pair represents a non-negativeinteger.For example I would like to extract 1, 255 and 18 from 01ff12 (as thecomponents of a simple RGB colour, in my application).I was hoping to find something like std::setw for istreams and use itin combination with std::hex so that I could read 2 hex digits at atime, but as far as I can tell no such entity exists in the C++standard library.Is there a neat and tidy way of doing what I want, or am I going tohave to do something nasty like put each digit pair in to its ownbuffer and stream-extract/strtoul the numbers from there?Why is it that no equivalent to setw exists for istreams?Kind Regards,Edd 解决方案There are a number of ways to approach the issue, and this is notneccessarily the best way.You could teach the computer how to count with hex char pairs.Extracting two chars from a std::istringstream or std::istream& isdandy but that will get you an ascii translation, not what you need.The Hex class''s const_char_array ctor takes 3 chars, not 2 (because ofnull termination).The cvt(...) function converts each hex digit to an unsigned equivalentwhile the ctor(s) init lists take care of calculating the finalunsigned result. Any hex digit that falls out of range generates anexception.This should be a portable solution. But that remains to be seen.#include <iostream>#include <ostream>#include <string>#include <stdexcept>class Hex{char m_16c; // left hex digit * 16char m_c; // right hex digitunsigned m_n; // resultpublic:Hex(const char (& array)[3]) // ctor, char array[3] by ref: m_16c(array[0]), m_c(array[1]),m_n(16*cvt(m_16c) + cvt(m_c)) { }Hex(std::string& s) // ctor, a string of 2 chars, others ignored: m_16c(s[0]), m_c(s[1]),m_n(16*cvt(m_16c) + cvt(m_c)) { }Hex(const Hex& copy) // copy ctor{m_16c = copy.m_16c;m_c = copy.m_c;m_n = copy.m_n;}// member functionsunsigned cvt(const char c) const{if(c >= ''0'' && c <= ''9''){return c - ''0'';} else if(c >= ''a'' && c <= ''f''){return 10 + (c - ''a'');} else if(c >= ''A'' && c <= ''F''){return 10 + (c - ''A'');} else{throw std::runtime_error("Hex out of range.");}}// friend operatorsfriend std::ostream&operator<<(std::ostream& os, const Hex& r_h){return os << r_h.m_n;}};int main(){try {// testing hex pairsHex h255("ff");std::cout << h255 << std::endl;Hex h16("10");std::cout << h16 << std::endl;Hex h0A("0A");std::cout << h0A << std::endl;// parsing a bufferstd::string buffer("ff100a");std::string red(buffer, 0, 2); // substrHex r(red);std::cout << "r: " << r << std::endl;std::string green(buffer, 2, 2);Hex g(green);std::cout << "g: " << g << std::endl;std::string blue(buffer, 4, 2);Hex b(blue);std::cout << "b: " << b << std::endl;}catch(std::exception& r_e){std::cerr << "Error: " << r_e.what();std::cerr << std::endl;}}/*2551610r: 255g: 16b: 10*/Note how the std::string buffer in main() is substringed and loadedinto individual Hex variables.Imagine a Colour class with 3 Hex members (r, g and b), appropriatectors and operator overloads and even a filereader function.You could open a file with std::ifstream and use std::getline to loadthat buffer one line at a time.[ generous code snipped ]Many thanks for you reply. I had come up with something equally longwinded. I was hoping that istreams would provide a way of doing thissimply as the task appears appropriate for their job description.In fact, I''m not sure your code is entirely portable. If I''m notmistaken it appears that you''re assuming that all character sets havealphabetical glyphs with contiguous values (i.e. they could doaAbBcCdD... as far as I''m aware).But it just goes to show how stupidly tricky such a problem is. Ireally am going to have to peel the characters off in to 2-digitbuffers and read from those :/Kind regards,EddHow about reading all six digits as one number from the stream,using std::hex and then extracting the three components usingthe modulo operation?That would save you the two-digit buffer but probably youwould run into little/big-endian issues.HTH,- J. 这篇关于istreams没有setw?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-22 16:53