【问题标题】:loading values of a text file into an array将文本文件的值加载到数组中
【发布时间】:2013-11-24 22:21:24
【问题描述】:

我从图形生成器生成的文本文件类似于:

:0 0|-   1|82  2|72
:1 0|87  1|-   2|74
:2 0|86  1|53  2|-

这些应该代表节点和到它们的距离。 第 1 行是:1 1|- 2|82 3|72 就是说从节点0到节点0(0|-)的距离是-(无穷大)

从节点0到节点1(1|82)是82

从节点 0 到节点 2 (2|72) 是 72

但我想将值加载到二维数组中。 上面的数组应该是

Graph[0][0] = -
Graph[0][1] = 82
Graph[0][2] = 72
etc... 

我只是不确定当我在 txt 文件中读取时如何捕获 :0 & :1 & :2 然后分隔 1|5。

任何帮助都会很棒! 谢谢!

【问题讨论】:

  • 1|5分开是什么意思?那是哪里?
  • 如果您认为您的输入文件和您在该手动编码数组中的表示之间的关联非常清晰,让我现在向您保证;它不是
  • 您可以将文件转换为字符串并从那里索引字符。但是,我对您的数组和文件的匹配方式仍然很模糊。

标签: c++ text-files multidimensional-array fstream


【解决方案1】:

一个问题是那些- 字符。如果您将它们替换为0,那么您可以使用类似于以下代码的内容:

// Open the file like this:
// std::ifstream fin ("whatever.txt");

char dummy;
for (int i = 0; i < n; ++i)
{
    int x, d;
    fin >> dummy >> x;  // read ":1", etc.
    assert (dummy == '=');
    assert (x == i + 1);
    for (int j = 0; j < n; ++j)
    {
        fin >> x >> dummy >> d;  // read "2|42", etc.
        assert (dummy == '|');
        assert (x == j + 1);
        Graph[i][j] = d;
    }
}

所有这些asserts 都在那里确保文件中的冗余数据与它们应有的一样。并且不要忘记将所有的 '-' 替换为 '0'。

你可以看到我在那里做什么。我正常读取整数,当':''|' 符号是时读取字符。

【讨论】:

  • '-' 代表'无穷大'。放弃 C++ 并使用 fgets 并“手动”解析是很诱人的。但是您仍然需要一种方法以 OP 使用的任何数据类型保存“无穷大”; Graph[0][0] = - 仅适用于字符串。
  • 转念一想:节点到自身的距离 0,不是很大的距离...(也许是为了阻止无限回溯?)
  • @Jongware:这是解决 OP 问题的最简单的代码。我不认为指针意大利面/手动解析/正则表达式在这里是好的解决方案。另外,正如我在回答中提到的那样,只需将 - 替换为 0 就可以使解析变得更加容易。
  • 是的,这是一个 C++ 解决方案,而我的是纯 C (...指针意大利面?认真吗?)。但是,您丢弃 '-'=INF 并建议 OP 更改他的数据。 IMO 完全没有必要。
  • @Jongware:我并不是说你的代码很糟糕。我要说的是,鉴于 OP 的问题和疑问,我认为任何使用任何指针操作和手动字符串处理的代码似乎都超出了他/她的 C/C++ 编程能力水平,所以我建议对数据进行小幅更改(这大大简化了解析代码,并且可以使用文本编辑器来实现)和我能想到的最简单的解决方案。
【解决方案2】:

一种简单的 C 方法,您可以将其重写为 C++ 或按原样使用。毕竟,这看起来不像是 C++ 关键代码。

注意fgets 使用最大 长度(当然,C++ 字符串在这里可以更好地工作)和#define 用于“无穷大”,因为您不能将此值存储在明智的方式。它假定您的所有距离都是正数,并且您的数据与您显示的一样(即,巨大 数字 > MAX_INT 或不一致的间距没有意外)。

cin 的常用 C++ 方法在这里不能很好地工作,fscanf 也不能,因为在这两种情况下你都需要读取 一个 字符,确定它是否是 -如果它没有重新读取它本身和它后面的任何数字。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_DATA_LENGTH 120
#define DIST_INFINITY   0xFFFFFFFF

unsigned int Graph[10][3];

int main (void)
{
    FILE *fp;
    char input_string[MAX_DATA_LENGTH], *token_ptr;
    int graph_counter = 0, i;

    fp = fopen ("graph.txt", "rt");
    if (!fp)
    {
        printf ("data not found\n");
        return -1;
    }

    do
    {
        if (fgets (input_string, MAX_DATA_LENGTH, fp) == NULL)
            break;
        token_ptr = input_string;
        for (i=0; i<3; i++)
        {
            token_ptr = strchr (token_ptr, '|');
            if (!token_ptr || !token_ptr[1])
                break;
            token_ptr++;
            if (*token_ptr == '-')
                Graph[graph_counter][i] = DIST_INFINITY;
            else
                Graph[graph_counter][i] = strtoul (token_ptr, NULL, 10);
            token_ptr++;
        }
        if (i < 3)
            break;
        graph_counter++;
    } while (1);

    for (i=0; i<graph_counter; i++)
        printf ("Graph[%d] = %u %u %u\n", i, Graph[i][0], Graph[i][1], Graph[i][2]);

    return 0;
}

【讨论】:

  • 我还假设:0 数字只是行号,0| 数字是索引。我的代码很高兴忽略它们,但如果它们意味着什么(即您的数据可能会从:10 行跳到:12 行,并且您需要保存该信息),它很容易调整。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-28
  • 1970-01-01
  • 2020-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多