Текстовый файл, который я генерирую из генератора графа, похож на:
: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
Но я хочу загрузить значения в 2d-массив. массив, указанный выше, должен быть
Graph[0][0] = -
Graph[0][1] = 82
Graph[0][2] = 72
etc...
Я просто не уверен, как при чтении в txt файле поймать: 0 &: 1 &: 2, затем отделить 1 | 5.
любая помощь была бы замечательной! Благодарю!
Одной из проблем являются те -
символы. Если вы замените их на 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;
}
}
Все эти assert
, чтобы убедиться, что избыточные данные в файле такие, какими они должны быть. И не забудьте заменить все "-" на "0".
Вы можете видеть, что я там делаю. Я обычно читаю целые числа и читаю персонажа, когда ':'
и '|'
символы.
fgets
и анализировать «вручную». Но вам все равно нужен способ сохранить «бесконечность» в любом типе данных, который использует OP; Graph[0][0] = -
будет работать только для строк.
Простой подход C, который вы можете переписать как C++ или просто использовать как есть. В конце концов, это не похоже на критический код C++.
Обратите внимание на использование максимальной длины для fgets
(предоставлено, строка C++ может работать лучше здесь) и #define
для "бесконечности", поскольку вы не можете сохранить это значение разумным способом. Предполагается, что все ваши расстояния положительны, и ваши данные, как вы показали (например, никаких сюрпризов, таких как огромные числа> MAX_INT или несогласованный интервал).
Обычный C++ подход cin
здесь не работает, и не работает 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
и вам нужно сохранить эту информацию), это легко настроить.
1|5
? Где это?