在C ++中使用strtok [英] Using strtok in C++

查看:228
本文介绍了在C ++中使用strtok的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想读取一个有输入(时间和价格)的文件: 12:23:31
67 12:31:23 78 [...] code>我创建了一个 struct ,它包含小时,
分钟和秒的值。我使用 strtok 来标记单个值
,并使用 atof 来存储它们。但是,当我尝试
来标记时间时,我得到一个错误:不能将 std :: string'转换为'char *',将参数1转换为'char *'

 结构时间
{
int hours;
int minutes;
int seconds;
double price;
};

int main()
{
字符串文件,输入;
time * time_array;
char * tok;

cout<< 输入要读取输入的文件名:;
cin>>文件;

ifstream file_name(file.c_str());

file_name>>输入;
file_name>>输入;

// while(!file_name.eof())
for(int i = 0; i <4; i ++)
{
time_array = ;
file_name>>输入;
tok = strtok(input,:); // ERROR HERE
while(tok!= NULL)
{
* time_array.hours = atof(tok [0]);
* time_array.minutes = atof(tok [1]);
* time_array.seconds = atof(tok [2]);
}
file_name>>输入;
* time_array.prine = atof(input);
}
}


解决方案

I对所有 1 的此作业不会使用 strtok 。如果你想使用C-like工具,然后使用fscanf读取数据:

 成为FILE *而不是ifstream。 
fscanf(file_name,%f:%f:%f%f,& hours,& minutes,& seconds,& price);

大多数编写C ++的人喜欢更安全的类型。一种可能性是使用基本相同的格式字符串来读取数据,方法是使用 Boost。格式



另一种可能性是使用流提取器:

  char ignore1,ignore2; 
file>>小时>> ignore1>>分钟>> ignore2>>秒>>价钱;

至于这是什么/工作原理:每个提取器从输入流读取一个项目。提取器为 float 每个读取一个数字。 char 的提取器每个读取一个字符。在这种情况下,我们希望看到: 99:99:99 99 ,其中 9 表示一个数字。因此,我们读取一个数字,冒号,数字,冒号,数字和另一个数字(提取器自动跳过空格)。两个冒号读入 char 变量,可以忽略,或者您可以检查它们是否为冒号,以验证输入数据是否为正确的格式。 / p>

这是一个完整的,可编译的技术演示:

  #include < iostream> 


int main(){
float hours,minutes,seconds,price;
char ignore1,ignore2;

std :: cin>>小时>> ignore1>>分钟>> ignore2>>秒>>价钱;

std :: cout<< H:<小时
<< M:<<分钟
<< S:<<秒
<< P:<<价格< \\\
;
return 0;
}

肯定有更多的可能性,但至少有一些合理的







  1. 说实话,我不确定有没有工作,我会使用 strtok ,但有一些地方,我可能是至少有点诱惑,或希望 strtok 没有那么糟糕的设计,所以我可以使用它。在这种情况下,我甚至看不到很多理由使用任何类似 strtok


I'm trying to read a file which has input(time and price) as: 12:23:31 67 12:31:23 78 [...] I created a struct which holds values of hour, minutes and seconds. I used strtok to tokenize the individual values and use atof to store them. However, I'm getting an error when I try to tokenize the time: cannot convert std::string' to 'char*' for argument 1 to 'char*'

struct time
{
    int hours;
    int minutes;
    int seconds;
    double price;
};

int main()
{
    string file, input;
    time* time_array;
    char* tok;

    cout << "Enter a file name to read input: ";
    cin >> file;

    ifstream file_name(file.c_str());

    file_name >> input;
    file_name >> input;

    //while(!file_name.eof())
    for(int i = 0; i < 4; i++)
    {
        time_array = new time;
        file_name >> input;
        tok = strtok(input, ":"); //ERROR HERE
        while(tok != NULL)
        {
            *time_array.hours = atof(tok[0]);
            *time_array.minutes = atof(tok[1]);
            *time_array.seconds = atof(tok[2]);
        }
        file_name >> input;
        *time_array.prine = atof(input);
    }
}

解决方案

I would not use strtok for this job at all1. If you want to use C-like tools, then read the data with fscanf:

// note there here `file_name` needs to be a FILE * instead of an ifstream.
fscanf(file_name, "%f:%f:%f %f", &hours, &minutes, &seconds, &price);

Most people writing C++ would prefer something more typesafe though. One possibility would be to use essentially the same format string to read the data using Boost.format.

Another possibility would be to use stream extractors:

char ignore1, ignore2;
file >> hours >> ignore1 >> minutes >> ignore2 >> seconds >> price;

As to what this does/how it works: each extractor reads one item from the input stream. the extractors for float each read a number. The extractors for char each read one character. In this case, we expect to see: 99:99:99 99, where 9 means "a digit". So, we read a number, a colon, a number, a colon, a number and another number (the extractor skips whitespace automatically). The two colons are read into char variables, and can either be ignored, or you can check that they really are colons to verify that the input data was in the correct format.

Here's a complete, compileable demo of that technique:

#include <iostream>


int main() {
    float hours, minutes, seconds, price;
    char ignore1, ignore2;

    std::cin >> hours >> ignore1 >> minutes >> ignore2 >> seconds >> price;

    std::cout << "H:" << hours 
              << " M:" << minutes 
              << " S:" << seconds 
              << " P:" << price << "\n";
    return 0;
}

There are certainly a lot more possibilities, but at least those are a few reasonable ones.


  1. To be honest, I'm not sure there's any job for which I'd use strtok, but there are some where I might be at least a little tempted, or wish strtok weren't so badly designed so I could use it. In this case, however, I don't even see much reason to use anything similar to strtok at all.

这篇关于在C ++中使用strtok的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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