[C++] Leer un archivo y meterlo en un array bidimensional

Iniciado por Kougami, 22 Febrero 2017, 14:47 PM

0 Miembros y 1 Visitante están viendo este tema.

Kougami

Buenas,

Tengo un problema, necesito leer un archivo que tiene la siguiente informacion:
#######
#   .####
#           #
#@#$    #
###      #
######

Donde son 7 columnas por 6 filas, y entonces necesito leer el archivo, con los espacios incluidos y guardarlo en un array bidimensional que esta dentro de un struct; tal que asi:
Código (cpp) [Seleccionar]

const int MAX = 50;
typedef char tTablero[MAX][MAX];
  typedef struct{
  tTablero tablero;
  int columnas;
  int filas;
  string nombreDelFichero;
}tJuego;

Pero teniendo en cuenta que al principio no se sabe cuantas filas y columnas tiene el archivo.

Muchas gracias de antemano

dato000

Necesitarias hacer lo siguiente:

1) Para obtener las columnas leer caracter por caracter sumando un contador y asignando la cantidad del mismo en la variable de columna. Dependiendo si tienes en una linea más caracteres que en la anterior linea, reasignar el contador y reasignarlo en la variable de columnas
2) Para obtener las filas leer la cantidad de lineas del archivo, nuevamente con otro contador de filas.

El problema que le veo es si tuvieras un caso desproporcionado de espacios, en la que quisieras leer espacios en una linea que tiene digamos un caracter '#' pero tuvieras en cuenta también espacios en blanco posteriores a ese caracter, creo que no es el caso, pero es importante tenerlo en cuenta.

Aqui encontre un ejemplo de un contador de caracterees de un archivo, puede que te sirva:

http://stackoverflow.com/questions/19416047/c-character-count-from-a-file


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

int main() {
  /* a buffer to hold the count of characters 0,...,256; it is
   * initialized to zero on every element */
  int count[256] = { 0 };

  /* loop counter */
  int k;

  /* file handle --- in this case I am parsing this source code */
  FILE *fp = fopen("ccount.c", "r");

  /* a holder for each character (stored as int) */
  int c;

  /* for as long as we can get characters... */
  while((c=fgetc(fp))) {

    /* break if end of file */
    if(c == EOF) break;

    /* otherwise add one to the count of that particular character */
    count[c]+=1;
  }

  /* now print the results; only if the count is different from
   * zero */
  for(k=0; k<256; k++) {
    if(count[k] > 0) {
      printf("char %c: %d times\n", k, count[k]);
    }
  }
  /* close the file */
  fclose(fp);

  /* that's it */
  return 0;
}


Puede que te sirva, ahora tengo una duda, estas armando un tetris??? porque hay otras formas... sin archivos.



ivancea96

Si el archivo solo va a tener esos datos, entonces puedes ver el tamaño del archivo y dividirlo entre el número de caracteres de la primera fila (sumando el salto de línea).
Luego, y alo puedes leer con ifstream y la función getline().

Por cierto, en C++ no necesitas poner typedef para declarar estructuras:

Código (cpp) [Seleccionar]
const int MAX = 50;
typedef char Tablero[MAX][MAX];

struct Juego{
   Tablero tablero;
   int columnas;
   int filas;
   string nombreDelFichero;
};

O
Código (cpp) [Seleccionar]
const int MAX = 50;

struct Juego{
   char tablero[MAX][MAX];
   int columnas;
   int filas;
   string nombreDelFichero;
};


Si no sabes hacer algo de lo comentado, indícalo.

Kougami

La cosa es que quiero hacer un sokoban, y en el archivo de texto estan todos los niveles seguidos y tienen distinto tamaño de filas y columnas, por lo que necesito un metodo que me guarde en el array un tablero segun el tamaño que este tenga

ivancea96

En ese caso, entre tablero y tablero, habrá algún separador. Una línea en blanco, quizás. Solo necesitas recorrer el archivo hasta encontrar ese separador. Ahí ya sabrás las filas y las columnas del tablero.

Kougami

Osea que primero debo de recorrer el archivo para saber el numero de filas y columnas, y luego sabiendo ese dato, recorrerlo y guardarlo en el array bidimensional no??

Pero la cosa es que no se como hacer para leer los espacios en blanco, que tambien debo guardar en el array

ivancea96

Tanto un '#' como un espacio son ambos caracteres, y tanto fread como fgetc como gran parte de las funciones los van a tratar de igual forma. Simplemente, leerás el espacio.

Y sí, recorrerlo primero es una opción. Otra opción es ir leyendo e ir ampliando la matriz (crear otra más grande, copiar contenido antiguo y liberar la antigua). Lo que más cómodo se te haga.

Kougami

La cosa es que para leer solo utilizo (Por orden explicita jajajaja) la forma tipo fich>> var; cin>>var; fich.get(var)

ivancea96

Oh cierto perdon, me confundí con el código de dato000.

Bien, el tema es, que ciertamente, cin>>string lee hasta salto de línea o espacios.
para leer una línea, getline(istream, string):
Código (cpp) [Seleccionar]
ifstream file(...);
string linea;
getline(file, linea);

// O, para leer de consola:

getline(cin, linea);

Kougami

Pero con el getline(), ¿Se leen tambien los espacios?