Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 假设只有最后一行有不包含3个值的错误,如何使用流提取操作符读取文件_C++ - Fatal编程技术网

C++ 假设只有最后一行有不包含3个值的错误,如何使用流提取操作符读取文件

C++ 假设只有最后一行有不包含3个值的错误,如何使用流提取操作符读取文件,c++,C++,文本文件即时读取 1 1 1 1.2 -2.3 0.4 -2 -3 -4 +0 -2 8.85 2.345 我的代码: #包括 #包括 使用名称空间std; 双读文件(ifstream&myfile、double&a、double&b、double&c); int main() { int计数器=0; 双a、b、c; 字符串行、输入文件、输出文件; cout>输入文件; 输出文件; ifstream myfile(inputFile); 如果(myfile.is_open()) { 而(!my

文本文件即时读取

1 1 1
1.2 -2.3 0.4
-2 -3 -4
+0 -2 8.85
2.345
我的代码:

#包括
#包括
使用名称空间std;
双读文件(ifstream&myfile、double&a、double&b、double&c);
int main()
{
int计数器=0;
双a、b、c;
字符串行、输入文件、输出文件;
cout>输入文件;
输出文件;
ifstream myfile(inputFile);
如果(myfile.is_open())
{
而(!myfile.eof())
{
读取文件(myfile、a、b、c、计数器);
计算(a、b、c);
}
}
否则不能>a>>b>>c;

cout
std::istream
operator>
无法从流中提取值时设置
failbit
。在您的代码中,
failbit
将被设置为无法解析为双精度的3个值,并且您可以查询
failbit
是否由
std::failbit()
设置

double readFile(ifstream&myfile、double&a、double&b、double&c)
{
我的文件>>a>>b>>c;
if(myfile.fail())
{
//如果a、b或c中的一个未成功解析,则设置failbit。
//在这里输入一些停止代码。
}

cout您最大的问题是
>
跳过了前导空格,因此它不能区分
'
(空格)或
'\n'
——它只是空格。要正确处理它,您需要将每行读入
std::string
,然后从该行创建
std::stringstream

然后用
>
std::stringstream
中读取三个
double
值。这样,您就不能读取比该行中更多的
double
值。否则,如果您尝试使用
>
,您将很高兴地从一行读取两个
double
值,从下一行读取第三个
值,而不需要没有任何迹象表明会发生这种情况

接下来,您需要函数指示从行中读取三个
double
值的成功/失败。您只需要返回类型
bool
。如果您读取三个有效
double
值,则返回
true
并执行
计算()
否则,如果返回
false
,请停止尝试读取文件

一个简单的例子是:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

bool read3doubles (std::ifstream& f, double& a, double& b, double& c)
{
    std::string line {};                /* std::string to hold line */
    
    if (getline (f, line)) {            /* if line read from file */
        std::stringstream ss(line);     /* create stringstream from line */
        if (ss >> a >> b >> c)          /* if 3 doubles read from line */
            return true;                /* return true */
    }
    
    return false;   /* otherwise, return false */
}

void calculations (double& a, double& b, double& c)
{
    std::cout << a << "  " << b << "  " << c << '\n';
}

int main (int argc, char **argv) {

    if (argc < 2) { /* validate at least 1 argument given */
        std::cerr << "error: insufficient number of arguments.\n"
                    "usage: " << argv[0] << " <filename>\n";
        return 1;
    }

    std::ifstream f (argv[1]);          /* open file-stream with 1st argument */
    double a, b, c;
    
    if (!f.good()) {    /* validate file open for reading */
        std::cerr << "errro: file open failed '" << argv[1] << "'.\n";
        return 1;
    }

    while (read3doubles(f, a, b, c))    /* while 3 doubles read from file */
        calculations (a, b, c);         /* do your calculation */
    
}

如果您还有其他问题,请告诉我。

我添加了一个不同的函数,可以按空格切掉一行并将其转换为数字。您的主函数基本上不受影响。虽然我做了一些更改,如添加了
std::vector
,但请尽早返回以删除一些嵌套

另外,我将主
while
条件从
eof
更改为
std::getline

  • std::string\u视图上的操作非常便宜

  • 通过这种方式,您可以在每一行上检查读取的值的数量始终是您所需要的

  • 对于错误输入,如果行/字不是数字,则可以通过在异常捕捉器中打印它来轻松调试

#包括
#包括
#包括
使用名称空间std;
无效读取值(标准::字符串视图行、标准::向量和值);
空隙计算(int,int,int);
int main()
{
字符串输入文件,输出文件;
cout>输入文件;
输出文件;
ifstream myfile(inputFile);
如果(!myfile.is_open()){

我先看看,然后打开警告,你应该为
readFile()
方法什么也不返回得到一个警告。感谢你解释我的代码有什么问题以及我如何改进它
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

bool read3doubles (std::ifstream& f, double& a, double& b, double& c)
{
    std::string line {};                /* std::string to hold line */
    
    if (getline (f, line)) {            /* if line read from file */
        std::stringstream ss(line);     /* create stringstream from line */
        if (ss >> a >> b >> c)          /* if 3 doubles read from line */
            return true;                /* return true */
    }
    
    return false;   /* otherwise, return false */
}

void calculations (double& a, double& b, double& c)
{
    std::cout << a << "  " << b << "  " << c << '\n';
}

int main (int argc, char **argv) {

    if (argc < 2) { /* validate at least 1 argument given */
        std::cerr << "error: insufficient number of arguments.\n"
                    "usage: " << argv[0] << " <filename>\n";
        return 1;
    }

    std::ifstream f (argv[1]);          /* open file-stream with 1st argument */
    double a, b, c;
    
    if (!f.good()) {    /* validate file open for reading */
        std::cerr << "errro: file open failed '" << argv[1] << "'.\n";
        return 1;
    }

    while (read3doubles(f, a, b, c))    /* while 3 doubles read from file */
        calculations (a, b, c);         /* do your calculation */
    
}
$ ./bin/read3doubles dat/3doubles.txt
1  1  1
1.2  -2.3  0.4
-2  -3  -4
0  -2  8.85
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

void read_values(std::string_view line, std::vector<double> &values);
void calculations(int, int, int);
int main()
{
  string inputFile, outputFile;

  cout << "Enter the name of your input file: ";
  cin >> inputFile;

  cout << "Enter the name of your output file: ";
  cin >> outputFile;

  ifstream myfile(inputFile);
  if (!myfile.is_open()) {
    cout << "unable to open file";
    return -1;
  }

  std::string line;
  std::vector<double> values;
  while (std::getline(myfile, line, '\n')) {
    read_values(line, values);
    std::cout << values.size();
  }
  return 0;
}

void read_values(std::string_view line, std::vector<double> &values)
{
  while (!line.empty()) {
    const std::string_view::size_type pos_space{line.find(' ')};
    try {
      values.push_back(std::stod(std::string(line.substr(0, pos_space))));
    }
    catch (const std::invalid_argument &ex) {
      std::cout << ex.what() << std::endl;
      return;
    }
    line.remove_prefix(pos_space + 1);
  }
}