1

我已经尝试了所有建议的方法来从单列文本文件中读取值。它们是 pos 和 neg 浮点值。我尝试过 boost、.atof()、.strtod()、get、getline、.push_back() 等等。我当前的代码将 0 分配给 cels。我尝试过的几乎所有其他函数都只给了我字符串 '\0' 并陷入了 while 循环。

如果你看一下程序的底部,我已经启动了 svg 来创建一个条形图。我需要能够找到最大值和最小值来创建比例因子,然后通过 svg 提供每个值。

我希望使用 .atof 或 getline ,因为它们似乎最有效。据我所知,不匹配的变量类型是一个问题。我为此付出了很多努力并重写了无数次。我想我很清楚我需要做什么,以及它应该如何工作,但我似乎无法把它们放在一起。我真的很感激任何帮助!

#include <iostream>
#include <fstream>
#include <sstream>
#include <istream>
#include <cstdlib>
#include <string>
#include <vector>
#include <cctype>
#include <cstdio>

using namespace std;

string html_start() { return("<!DOCTYPE html>\n<html>\n<body>\n\n"); }
string html_end()   { return("\n</body>\n</html>\n\n"); }
string svg_start()  { return("<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 1024 768\" preserveAspectRatio=\"xMinYMid meet\" >\n"); }
string svg_end()    { return("</svg>\n"); }



int main ()
{
    ifstream infile ("parsableTemps.txt");
    ofstream fout ("graph.html", std::ofstream::out);
    double cels, fahr, maxnum = -50, minnum = 150;
    int column = 10, width = 5;
    string number;
    //char c;

    infile.open("parsableTemps.txt");
    infile.is_open();
    if (infile.is_open())
    {
    while (! infile.eof())
    {
        std::getline (infile,number);
        //while (! isspace(c))
        //{
        //    infile >> number;
        //}


        //cels = atof(number.c_str());
        char *end;
        //std::getline(infile, number);
        //cout << number;
        cels = strtod(number.c_str(), &end);
        fahr = (9/5 * cels) + 32;

        if (fahr > maxnum)
        {
            maxnum = fahr;
        }

    if (fahr < minnum)
    {
        minnum = fahr;
    }


    fout.open("graph.html");
    fout << html_start();
    fout << "<h1> AVERAGE TEMPERATURE </h1>\n";
    fout << svg_start();

    fout << "   <rect x=\"" << column << "\" y=\"" << maxnum - fahr << "\" width=\"" << width << "\" height=\"" << fahr << "\" style=\"fill:rgb(255,0,0);stroke-width:1;stroke:rgb(0,0,0)\"/>\n";

    column += width;

}
}
else
{
    cout << "error";
}

//cout << maxnum << " " << minnum;

fout << svg_end();
fout << html_end();
fout.close();
infile.close();
return 0;
}
4

3 回答 3

2

我怀疑这个问题的措辞很糟糕。在执行任何其他操作之前,请停止两次打开输入文件:

ifstream infile ("parsableTemps.txt");
//...
infile.open("parsableTemps.txt");//<- Why twice?

这就足够了:

ifstream infile ("parsableTemps.txt");
//...

其次,不要在循环期间不断重新打开输出文件。在循环外打开一次:

ofstream fout ("graph.html", std::ofstream::out); //moved...
fout << html_start();                             //moved...
fout << "<h1> AVERAGE TEMPERATURE </h1>\n";       //moved...
fout << svg_start();                              //moved...

if (infile.is_open())
{
    while (! infile.eof())
    {

您发布的代码说

   while (! infile.eof())
    {
        std::getline (infile,number);
        //...
        fout.open("graph.html");
        //...
        fout << "   <rect x=\"" << column << "\" y=\"" << maxnum - fahr << "\" width=\"" << width << "\" height=\"" << fahr << "\" style=\"fill:rgb(255,0,0);stroke-width:1;stroke:rgb(0,0,0)\"/>\n";

这将一遍又一遍地覆盖以前的文件。此外,在您完成循环之前,您还没有找到整体的最小值和最大值,所以也许您应该稍后再写?

在输入方面,它适用于我的机器。

于 2013-08-06T12:03:37.227 回答
0

好的,现在它对我有用

你的 while 循环:

while ( !infile.eof() )
{
    char *end;
   infile>>number; // Just read a number as string
    cels = strtod(number.c_str(), &end); // Can use other method too
    fahr = (9/5 * cels) + 32;

    if (fahr > maxnum)
    {
        maxnum = fahr;
    }

    if (fahr < minnum)
    {
        minnum = fahr;
    }

    //fout.open("graph.html"); // Don't reopen
    fout << html_start();
    fout << "<h1> AVERAGE TEMPERATURE </h1>\n";
    fout << svg_start();

    fout << "   <rect x=\"" << column << "\" y=\"" << maxnum - fahr << "\" width=\"" << width << "\" height=\"" << fahr << "\" style=\"fill:rgb(255,0,0);stroke-width:1;stroke:rgb(0,0,0)\"/>\n";

    column += width;
}

将单个数字读取为字符串然后应用strtod它,您正在阅读整行。也不要重新打开打开的文件进行写入和读取

不确定您是否得到正确的 graph.html,但它会根据输入数量和您的算法写入该行。

于 2013-08-06T12:13:17.907 回答
0

使用strtod()是一件很痛苦的事情:我也遇到了很多麻烦(因为指针应该总是在正确的位置,等等)。

最简单的解决方案是使用更宽松的自定义功能模板(在 StackOverflow 上的某处找到):

template <typename T>
T StringToNumber(const std::string &Text, const T defValue = T()) {
    std::stringstream ss;
    for(const char i : Text)  // C++11; can be replaced by an iterator
        if(isdigit(i) || i == 'e' || i == '-' || i == '+' || i == '.')
            ss << i;
    T result;
    return ss >> result ? result : defValue;
}

main()函数中:

std::getline(infile,number);
cels = StringToNumber(number, 0.0);

对于每行有多个数字的文件,我使用 astd::vector<std::string>来分隔不同的“单词”(我的意思是用空格或换行符分隔的字符序列):

std::vector<std::string> WordsToVectorOfWords(const std::string &Text) {
    std::vector<std::string> VectorOfWords;
    std::string word;
    for(const char i : Text) {  // C++11; can be replaced by an iterator
        if(i == ' ' || i == '\t' || i == '\n') {
            VectorOfWords.push_back(word);
            word = "";
            continue;
        }
        word += i;
    {
    return VectorOfWords;
}

main()函数中:

std::getline(infile,number);
std::vector<std::string> VectorOfWords = WordsToVectorOfWords(number);
for(const srd::string Words : VectorOfWords) {  // C++11; can be replaced by an iterator
    cels = StringToNumber(Words, 0.0);
    ...
    }
于 2013-08-06T11:46:29.980 回答