格式化CString函数 [英] Formatting a CString function

查看:77
本文介绍了格式化CString函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我必须检查其是否为特定格式并打印.但是我的代码给出了一些运行时错误.

这是我的代码.这是文件中必须读取的一行:

Hello, I have and I have to check if its in a particular format and print. But my code is giving out some runtime error.

here''s my code.This is a line from a file that has to b read:

bool ParseFile (CString const& line, CV3& point) const
 1)for a file which has string like this :="618.888,201.88"

 CString searchString;
 searchString.Format(_T("%%lf%s%%lf"), lineSepChar[seperator]);
//the %s takes the value from the seperator, say comma 
if(swscanf_s(line, searchString , &point.y, &point.x) == 2 )
// the point is a vector class and has 3 variables x, y and z
return true; 
}
// this works fine 


但是当输入字符串时:


But when for a string:

bool ParseFile (CString const& line, CV3& point) const
2)for a file which has string like this :="618.888,201.88,abcdefg,hijk"

 CString searchString;
 searchString.Format("%%lf%s%%lf%s%%s%s%%s"),s_lineSepChar[m_srcSep], s_lineSepChar[m_srcSep], s_lineSepChar[m_srcSep]);


 if(swscanf_s(line, searchStr, &pt.y, &pt.x, str1, 50, str2, 50 ) == 4 )
return true; 


但是对于第二个示例,str1和str2都采用"abcdefg,hijk"的值,并且返回值为false ...

但是如果我改变


But for this second example both str1 and str2 take the value of "abcdefg,hijk" and the return value is false ...

But if I change

swscanf_s(line, searchStr, &pt.y, &pt.x, str1, 50, str2, 50 ) == 4 




to

swscanf_s(line, searchStr, &pt.y, &pt.x, str1, 50, str2, 50 ) == 3 


返回值是true,它是str1和str2的重复值;


The return value is true, its the duplicate values for str1 and str2;

推荐答案

如果您忘记了scanf 及其所有内容,您的生活将变得更加轻松"的野兽孩子每一个都存在. C ++有一种更好的方式来读取格式化的数据-它被称为流.流已经为它们定义了提取操作,因此您不必费心管理字符缓冲区,而且上帝知道其他什么.因此,当您想读取string时,您也要读取string.当您想阅读int时,您阅读了int.等等...

如果您有要在此处解析的CSV文件,则是一种读取和标记该文件的一般方法:

-将文件中的一行(使用std::getline)读入std::string
-使用(std::replace)
替换该行中的所有逗号 -在您刚刚完成替换的那一行上创建一个std::istringstream
-从std::istringstream
中提取所需的值
所以...如果您有以下格式的CSV:

-机场代码(三个字母的字符串)
-一品脱啤酒的价格(整数,需购买的便士数量)
-当人们看到一品脱的价格时,每年造成的伤亡人数

这是Ash的一种快速而肮脏的机场啤酒解析器:
Your life would be so much easier if you forgot that scanf and all it''s beastly children every existed. C++ has a far better way of reading formatted data - it''s called a stream. Streams have extraction operations defined for them so you don''t have to fanny about managing character buffers and god knows what else. So when you want to read a string, to you read a string. When you want to read an int, you read an int. And so on...

If you''ve got a CSV file that you want to parse here''s a general way of reading and tokenising it:

- read a line from the file (using std::getline) into a std::string
- replace all the commas in the line using (std::replace)
- build a std::istringstream from the line you''ve just done the replacement on
- extract the values you want from the std::istringstream

So... if you''ve got a CSV in the following format:

- Airport code (three letter string)
- Price of a pint of beer (integer, number of pennies it costs to buy)
- Number of casualties caused per year when people see the price of a pint

Here''s Ash''s quick and dirty airport beer parser:
struct airport_beer_data
{
    airport_beer_data():
        price_per_pint_in_pennies_( 0 ),
        heart_attacks_per_year_( 0 ) {}

    std::string airport_code_;
    int price_per_pint_in_pennies_;
    int heart_attacks_per_year_;
};

airport_beer_data read_next_beer_data( std::istream &str )
{
    airport_beer_data beer_data;
    std::string line;
    if( str )
    {
        if( std::getline( str, line ) && !line.empty() )
        {
            std::replace( begin( line ), end( line ), ',', ' ' );
            std::istringstream line_parser( line );
            line_parser >> beer_data.airport_code_
                        >> beer_data.price_per_pint_in_pennies_
                        >> beer_data.heart_attacks_per_year_;
        }
    }

    return beer_data;
}

无需手动调整缓冲区大小,无需摆弄格式字符串,呜呼!

您可以使用以下命令进行测试:

No manual sizing of buffers, no fiddling about with format strings, woo hoo!

You can test drive it using something like:

std::istringstream input( "LHA,600,3000" );
auto first_data = read_next_beer_data( input );

或什至:

auto first_data = read_next_beer_data( std::cin );

如果要直接从命令行输入测试数据.

对于您的问题,您唯一需要更改的行是进行提取的行(以line_parser >>开头),这比摆弄scanf容易得多.几乎没有错误检查,但是不难坚持(老实,只需在提取后检查line_parser的状态).

因此,只需对scanf及其配对对象说不,除非您使用C语言进行编程.

if you want to enter test data directly from the command line.

For your problem the only line you''d have to change is the one that does the extraction (starts with line_parser >>), which is a lot easier than fiddling around with scanf. There''s very little error checking but that''s not hard to stick in (honest, just check the state of line_parser after the extractions).

So just say no to scanf and its mates, unless you''re programming in C.


我建​​议将字符串拆分为一个容器(例如,std::list) ,从容器中删除不需要的条目,然后重新加入容器.
从此处开始: STL拆分字符串功能 [
I''d suggest splitting the string into a container (e.g., std::list), removing the entries you don''t want from the container, and then re-joining the container.
Start here: STL split string function[^].

Hope this helps,
Pablo.


您昨天也问过类似的问题.请注意,使用swscanf _s 时,必须在以下参数中为每个字符串变量指定缓冲区长度,例如:

You have asked a similar question yesterday. Please observe that when working with swscanf_s you have to specify a buffer length for every string variable in the following parameter, e.g.:

if (swscanf_s (line, searchStr, str1, 50, str2, 50, str3, 50, doub1, chart1) == 7 )



将50替换为str1,... sttr3缓冲区的缓冲区长度.

现在您已经显示了更多的代码,我看到了另一个问题.您不能简单地分配一个CString变量并将其用作缓冲区.而是使用以下技术:



Replace 50 with the buffer length of your str1, ... sttr3 buffers.

Now that you have shown more of your code, I see another problem. You can''t simply allocate a CString variable and use it as buffer. Instead use the following technique:

TCHAR str1 [50];
TCHAR str2 [50];
TCHAR str3 [50];
double doub1;
char chart1;
swscanf_s (line, _T("%[^,],%[^,],%[^,],%lf,%c", str1, 50, str2, 50, str3, 50, &doub1, &chart1)



这将为您提供该行的前五个值.如果要将str1 ... 3分配给可以的CString,例如:



That will give you the first five values on the line. If you want to assign str1 ... 3 to a CString that''s fine, for example:

CString s1 = str1;



CString还有其他技术可以使CString为您分配缓冲区,但是对于您的编程级别而言,它们仍然太先进了.



There are other techniques with CString that would make it possible to have CString allocate the buffer for you, but they are still too advanced for your programming level.


这篇关于格式化CString函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆