0

I'm kind of a newbie in C++ programming.. My command prompt output is a big bulk (repeated) of the characters I have in my txt file. I create a 2d array map[15][15] and try to read the txt file. the reading part is ok but now I dunno how to put them in a 2D character array..

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

char map[15][15];
int alp = 0;
int i = 0;
int main()
{
  ifstream in;
  //string s;

  in.open("city.txt");
  if(!in.is_open())
  {
    cout << "File open error! " << endl;
  }
  else
  {
    while(!in.eof())
    {
      //getline(in, s);
      in >> map[i];
      i++;
      alp++;
      //if(in.eof()) break;
      cout << map[i] << endl;
    }
  }
  for(i = 0; i <= alp; i++)
  {
    cout << map[i];
  }

  in.close();
  return 0;
}
honk
  • 9,137
  • 11
  • 75
  • 83
  • 1
    `while(!in.eof())` [No!](http://stackoverflow.com/q/5605125/560648) What learning resource has taught you to do that? I need to know so that I may begin disrecommending it. – Lightness Races in Orbit Mar 13 '14 at 10:21
  • How is the data stored in the file? Is the data stored per line or per column? Are there spaces or newlines separating data? Maybe you can edit your question to include an example file? – Some programmer dude Mar 13 '14 at 10:25
  • my lecturer taught me.. it's to perform the task while it's not end of file, is that wrong? I was told this is in case the user pressed Enter after the last data in the txt file..I used getline(in,s) and if(in.eof()) break; in 1st step to display the characters.. then while referring to other questions I added the for() part.. – user3414728 Mar 13 '14 at 10:26
  • I need to store in a 2D array that has 15 elements with 15 (rows or data) in each element.. there's no separating data, cuz I need to create a map like this: xxxrxxxrxxrxrxx rrrrxrrrxrrrrrr xxxrxxxrxxrxrxx rrrrrrrrrrrrrrx xxxrxcxcxxxrxrr xxrrccxcxccrrrx xxrxxcxcxcxrxrx rrrrxcccccxrxrx xxrxxcxxxcxrxrx rrrrccxccccrrrr xxxrxcxcxcxrxrx rrxrxrrrrrxrxrr xrxrxrxrxrxrxrx rrrrrrxrxrrrrrr xxrxxrxrxrxxxxx – user3414728 Mar 13 '14 at 10:29
  • There's nothing separating even the rows? So in the file it's like `xxxrxxxrxxrxrxxrrrrxrrrxrrrrrrxxxrxxxrxxrxrxxrrrrrrrrrrrrrrx...` etc.? – Some programmer dude Mar 13 '14 at 11:01
  • there is. every 15 characters then enter nxt line and 15 and so on. – user3414728 Mar 13 '14 at 11:08

2 Answers2

0

eof() will only return true only after the first failed read operation. That operation will not be caught by your code. You could have a test for eof directly after the read and then break if eof(), but that's not elegant:

IO operations on streams return a ref to the given stream. Streams have a meaningful conversion to bool. True indicates that the read was successful, e.g. eof wasn't reached yet, and the read target contains a new correct input value. The idiomatic way of using this feature is "while(in >> map[i])".

As to the algorithm: You say that there are no spaces and I assume it's all ascii chars, so it boils down to double looping over the array's lines and columns with two for loops. Inside those loops would be a line reading each character explicitly with get() like

if(!cin.get(map[i][j])) {/* unexpected eof/io error, abort or whatever */ }
Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62
  • Do nothing in the loop body, except perhaps increase the index variables? – Some programmer dude Mar 13 '14 at 11:00
  • This is a statement nested in two for loops which I mentioned in the text but didn't code out. Maybe misunderstandable... – Peter - Reinstate Monica Mar 13 '14 at 11:08
  • @Joachim Right, that was a superfluous while loop... One could actually C like use a simple char* and just increment it for 15*15 times in a single loop, would be less wordy. – Peter - Reinstate Monica Mar 13 '14 at 11:14
  • If we can rely on the right file size we can write "for( char *p = (char *)map; in.get(*p); ++p);" . – Peter - Reinstate Monica Mar 13 '14 at 11:21
  • Guys I have the solution given by my lecturer: #include #include #include using namespace std; int main() { ifstream in; char s; char map[15][15]; int i,j, r = 0, c = 0; in.open("city.txt"); if(!in.is_open()) { cout << "File open error! " << endl; } else { while(!in.eof()) { in >> s; if(in.eof()) break; map[r][c] = s; c++; if(c > 14) { r++; c = 0; } } in.close(); for(i = 0; i < 15; i++) { for(j = 0; j < 15; j++) cout << map[i][j]; cout << endl; } } return 0; } Thx guys! – user3414728 Mar 20 '14 at 07:51
  • What I like about it is (1) using operator>>(char&) deals with arbitrary file formats (with/without line breaks, spaces etc.) (2) the code contains "c++" ;-). What I find doubtful is (1) the redundant while(eof) because, correctly, the code checks for eof after each lines and breaks the loop anyway, so the while can never be true (even not with an empty file, before the first read attempt). (2) And then, a 2-dimensional array just calls for a nested index loop, or is that just me? Emulating the loop by resetting the indices after (if > 14) seems too low-level. Can I post this at code review? – Peter - Reinstate Monica Mar 20 '14 at 08:23
0

As the data is textual, and separated into lines, I suggest you read directly into the sub-array using e.g. std:istream::getline:

for (size_t i = 0; in.getline(map[i], 15); ++i)
    ;
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621