2015-12-14 6 views
5

Как и в названии, я пытаюсь прочитать неизвестное количество целых чисел из файла и поместить их в массив 2d.Как читать 2-й массив из файла, не зная его длины в C++?

#include <iostream> 
#include <fstream> 
using namespace std; 
int main() 
{ 

fstream f;int i,j,n,a[20][20];char ch; 

i=0;j=0;n=0; 
f.open("array.txt", ios::in); 
while(!f.eof()) 
{ 
    i++; 
    n++; 
    do 
    { 
     f>>a[i][j]; 
     j++; 
     f>>ch; 
    } 
    while(ch!='\n'); 
} 

for(i=1;i<=n;i++) 
{ 
    for(j=1;j<=n;j++) 
     cout<<a[i][j]<<endl; 
    cout<<endl; 
} 
return 0; 

}

и мой файл "array.txt":

1 1 1 
2 2 2 
3 3 3 

После компиляции программы, она выводит эту

enter image description here

+1

Вы уверены, что вы не означает 'в то время (ч = '\ п'!)'? Изменить: Кроме того, вы можете перевернуть порядок 'f >> ch' и' f >> a [i] [j] '. – forkrul

+0

Добро пожаловать в переполнение стека. Не отправляйте ссылки на вывод, публикуйте фактический вывод. Сначала попробуйте что-то более простое: чтение в простой (1D) массив. Не используйте 'while (! F.eof())'. – Beta

+0

Я попробую ваши предложения. Изменить: ничего не возвращает. – NacRonDX

ответ

3

Поскольку ваш входной файл ориентирован на линию, вы должны использовать getline (эквивалент C++ или C fgets) для чтения строки, а затем istringstream для синтаксического анализа строки в целые числа. И поскольку вы не знаете размер, вы должны использовать векторы и постоянно контролировать, что все строки имеют одинаковый размер и количество строк совпадает с количеством столбцов.

И последнее, но не менее важное: вы должны проверить eof сразу после a читать, а не начинать цикл.

код становится:

#include <iostream> 
#include <fstream> 
#include <vector> 
#include <string> 
#include <sstream> 
using namespace std; 
int main() 
{ 

    fstream f; 
    int i=0, j=0, n=0; 
    string line; 
    vector<vector<int>> a; 
    f.open("array.txt", ios::in); 
    for(;;) 
    { 
     std::getline(f, line); 
     if (! f) break; // test eof after read 
     a.push_back(vector<int>()); 
     std::istringstream fline(line); 
     j = 0; 
     for(;;) { 
      int val; 
      fline >> val; 
      if (!fline) break; 
      a[i].push_back(val); 
      j++; 
     } 
     i++; 
     if (n == 0) n = j; 
     else if (n != j) { 
      cerr << "Error line " << i << " - " << j << " values instead of " << n << endl; 
     } 
    } 
    if (i != n) { 
     cerr << "Error " << i << " lines instead of " << n << endl; 
    } 

    for(vector<vector<int>>::const_iterator it = a.begin(); it != a.end(); it++) { 
     for (vector<int>::const_iterator jt = it->begin(); jt != it->end(); jt++) { 
      cout << " " << *jt; 
     } 
     cout << endl; 
    } 
    return 0; 
} 
1

Вы можете посмотреть в использование вектора, чтобы вы могли иметь динамический массив.

0

Try:

#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <string> 
using namespace std; 
int main() { 
    fstream f; 
    int i, j, n, a[20][20]; 
    string buf; 

    i = 0; 
    j = 0; 
    n = 0; 
    f.open("array.txt", ios::in); 
    while (1) { 
    getline(f, buf); 
    if (f.eof()) break; 
    stringstream buf_stream(buf); 
    j = 0; 
    do { 
     buf_stream >> a[i][j]; 
     j++; 
    } while (!buf_stream.eof()); 
    i++; 
    n++; 
    } 

    for (i = 0; i < n; i++) { 
    for (j = 0; j < n; j++) cout << a[i][j] << " "; 
    cout << endl; 
    } 
    return 0; 
} 

Кроме того, если вы действительно хотите читать сколь угодно большие массивы, то вы должны использовать std::vector или какой-либо другой контейнер, например, не сырые массивы.

+1

Рекомендовать tweak: 'while (getline (f, buf))' вместо 'while (1)', отдельные 'getline' и' if' и 'break'. Также предотвращает, по-видимому, редкий случай ошибки потока в 'getline' без eof, что приводит к неопределенному содержимому в' buf'. – user4581301