如何计算文件中的“列”数?

时间:2018-11-01 17:02:31

标签: c++ ifstream

我已获得以下功能;

SearchSerializer

为了使它正常工作,我需要知道文件中的行数和列数,才能将它们传递给此函数。我已经计算出使用的行数;

double* insert(char *file_Name, int Rows, int Columns)
{
 double* input = new double[Rows*Columns];
 //insert function code
}

但是,要弄清楚文件中有多少列,我遇到了很多麻烦。

我尝试过的一种方法是尝试查找'\ n'的所有实例并在每个实例上增加一个计数器;

int RowCount = 0;
string rows;

while (getline(myfile, rows)) {
    RowCount++;
}

while循环本身从未触发,因此“ ColumnCount”保持为0

文件本身是大量数字的集合,每个数字都由空格分隔。

2 个答案:

答案 0 :(得分:1)

因为我很无聊...

这肯定在边缘情况下存在错误(特别是与在行尾找到的定界符有关; meh),但适用于示例输入,并且(通常)显示了一种可能的方法。

#include <iostream>
#include <sstream>
#include <cstring>

bool CharIsIn(const char c, const char* str, const size_t strLen)
{
    for (size_t i = 0; i < strLen; i++)
        if (str[i] == c)
            return true;
    return false;
}

// Detects the number of subsequences of "delimiters" in the line.
// 
// By default a valid delimiter is either whitespace or a tab character,
// and "empty" columns are collapsed.
size_t DetectNumColumns(
    const std::string& line,
    const char* delimiters = " \t",
    const bool collapseEmpty = true
)
{
    if (line.empty())
        return 0;

    const size_t delimsLen = std::strlen(delimiters);

    size_t result = 1;

    bool lastWasDelim = true;

    for (size_t pos = 0; pos < line.size(); ++pos)
    {
        if (CharIsIn(line[pos], delimiters, delimsLen))
        {
            if (!lastWasDelim || !collapseEmpty)
                result++;
            else if (pos == line.size()-1 && lastWasDelim && !collapseEmpty)
                result++;
            lastWasDelim = true;
        }
        else
        {
            lastWasDelim = false;
        }
    }

    return result;
}

int main()
{
    // Simulating your input file
    std::stringstream ss;
    ss << "1.5 7.6\n";
    ss << "2.3 4.5\n";
    ss << "9.9 7.5\n";

    bool GotColumnCount = false;
    int RowCount = 0, ColumnCount = 0;
    std::string line;
    while (std::getline(ss, line))
    {
        // On the first iteration (only!) count columns.
        const int columns = DetectNumColumns(line);

        if (!GotColumnCount)
        {
            // On the first iteration, store this.
            ColumnCount = columns;
            GotColumnCount = true;
        }
        else
        {
            // On subsequent iterations, just ensure the column
            // count is consistent.
            if (columns != ColumnCount)
                throw std::out_of_range("Inconsistent column count in input");
        }

        // Always increment the row count (this bit's easy)
        RowCount++;
    }

    std::cout << "The input consists of " << RowCount << " rows of " << ColumnCount << " columns\n";
}

live demo

重点在于,您需要解析至少一行文本,以找出分隔符出现了多少次(或分隔符序列出现了多少次,具体取决于您的实际要求) )。您可能需要解析文本的每一行,以验证整个文件中的列数是否一致。

我故意不修复这些错误,不仅是因为我不能被打扰(尽管这确实是事实),而且也劝阻您不要简单地复制/粘贴此示例作为您的解决方案!请使用它来启发灵感,并提出更好的建议。

提示:如果分隔符始终只是单个字符(例如,单个空格),并且您不需要宽大处理诸如添加的前导或尾随空格之类的内容,则DetectNumColumns会比我上面的尝试变得更加简单;它实际上只是在计数(但请确保count your fence's panels, rather than its posts!)。

答案 1 :(得分:0)

您可以使用stringstream并假设各行具有不同的列。

编辑:对于您而言,您可能不需要maxColumnCount。只需计算列数并中断即可。

int maxColumnCount = 0;
string row;

while (getline(myfile, row)) {
    RowCount++;
    std::istringstream iss(row);
    int columnCount = 0;
    for(string columnValue; iss >> columnValue; )
        columnCount++;
    if(columnCount > maxColumnCount)
        maxColumnCount = columnCount ;

}