Hacer array de 2D a través del split de una string con un delimitador

Iniciado por z3nth10n, 19 Septiembre 2013, 20:13 PM

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

z3nth10n

Hola bueno, esta va a ser la primera pregunta que haga de C++ en el foro...

Y bueno, pues yo creo que es de nivel...
xD

Código (cpp) [Seleccionar]
#include <iostream>
#include <string>

int main()
{
std::string s = "0,0,0,1,1,1,0,0,1";
std::string delimiter = ",";

int x = 0;
std::string mapa[9];

size_t pos = 0;
std::string token;
while ((pos = s.find(delimiter)) != std::string::npos) {
   token = s.substr(0, pos);
   std::cout << token << std::endl;
   s.erase(0, pos + delimiter.length());

   mapa[x] = token;
   x++;
}
std::cout << s << std::endl;
cin.get();
}


Básicamente esto obtiene la dimensión X de la array, pero ahora necesito la segunda que básicamente sería la Y, con otro delimitador...

Tengo 2 problema 1 es que no se como hacerlo y 2 es que:

Código (cpp) [Seleccionar]
std::cout << s << std::endl;

Esto obtiene el último string que sería un 1:

Citar"0,0,0,1,1,1,0,0,1"

Como haría para que mostrase todo sin tener que hacer cosas raras... ?

Y por si queréis el archivo de texto del que extraigo todo el mejunje:

Citar0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

Gracias a todo aquel que me quiera guiar y/o hacer el code!
Un saludo. ;D

Me han dicho que use vectores, pero no tengo ni la mas mínima idea de como se usan... xD

Interesados hablad por Discord.

0xDani

A ver si lo he entendido: tienes una entrada, que es la que muestras en el archivo; y quieres generar una salida, que es un array bidimensional de caracteres, de forma que el array contenga en los índices x e y lo mismo que hay en esas coordenadas en el archivo.

Lo que veo es que puedes tener un array:

Código (cpp) [Seleccionar]
char myArray[MAX_ROWS][MAX_COLUMNS];

También te lo puedes hacer dinámico pero eso ya es cosa tuya.

Entonces lo que haces es que lees un carácter del archivo, y si es distinto de un salto de línea lo guardas en el array, en la posición de la fila actual, y en la de la columna anterior más 1. Si es un salto de línea, entonces sumas uno a la fila actual y pones la columna a cero otra vez.

Código (cpp) [Seleccionar]

size_t row=0, column=0;
std::string s;
while(getline(file, s))
{
    size_t i=0;
    while(s[i]!='\n')
    {
         myArray[row][column++] = s[i];
    }
    row++;
    column = 0;
}
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM

z3nth10n

#2
Me resulta bastante curioso tu code, ya que encontre este:

Código (cpp) [Seleccionar]
fstream fstr;
fstr.open("file.txt",ios::in);
string str;
int yDimension = 0;
while(getline(fstr,str)
{
   yDimension++;   //do appropriate thing with the y dimension
   std::string token;
   while ((pos = str.find(delimiter)) != std::string::npos) {
       token = str.substr(0, pos);
       std::cout << token << std::endl;
       str.erase(0, pos + delimiter.length());
       mapa[x] = token;
       x++;
   }
}


Que por cierto está mal hecho... (El code de arriba ^^)

He estado probando, y por alguna extraña razon tu code:

Código (cpp) [Seleccionar]
#include <iostream>
#include <string>
#include <fstream>


using namespace std;

fstream myfile;
size_t row=0, column=0;
std::string s;
int myArray[30][10];

int main() {

myfile.open("mapa.txt");

while(getline(myfile, s))
{
   size_t i=0;
   while(s[i]!='\n')
   {
        myArray[row][column] = s[i];
        std::cout << myArray[row][column];
        column++;
   }
   row++;
   column = 0;
}

std::cout << myArray[3][1] << std::endl;
std::cin.get();

return 0;
}


(Editado un poco) Hace una cosa rarisima, xD Muestra 48 en la consola y cuando lleva 4 lineas crashea xD Eso en un milisegundo y me resulta curioso no se porque... :P




Me he tomado la molestía y con la ayuda de Skatewinner he hecho esto:

Código (cpp) [Seleccionar]
#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int main()
{

fstream fstr;
fstr.open("mapa.txt");

int mapa[31][9], x = 0, y = 0;
char c;
while(fstr.good())
{
   c = fstr.get();
   if (c!= ',') {
       mapa[x][y] = c;
       x++;
   }
   if (c=='\n')
   {
       x = 0;
       y++;
   }
}

fstr.close();
cin.get();

}


Es lo más sencillo que lo he podido hacer.. :P
Y sin embargo sigo teniendo el mismo problema del 48... :/






Ya se a que se debe, se debe a que el array lo almacena todo en ascii y si le digo que lo muestre en entero pues va a mostrar el entero del ascii xd

Interesados hablad por Discord.

0xDani

Umm, claro, en mi code no he tenido en cuenta las comas. De todas formas, el que crashee depende del tamaño que le hayas puesto al array.
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM

z3nth10n

Bueno tio, gracias por las molestias que te tomas, pero ya hace 1 día que termine todo el cacharrerio con ayuda de skatewinner y en esto se quedo la función:

Código (cpp) [Seleccionar]
std::ifstream ifile("mapa.txt");
if (ifile) {
fstr.open("mapa.txt");

char mapa[worldWidth][worldHeight];
int x = 0, y = 0;
char c;
while(fstr.good())
{
    c = fstr.get();
    if (int(c) != -1 && c!= ',' && c!= '\n') {
        mapa[x][y] = c;
        x++;
    }
    if (c=='\n')
    {
        x = 0;
        y++;
    }
}

        for (int x = 0; x<worldWidth; x++) {
            for (int y = 0; y<worldHeight; y++) {
                sf::Texture texture;
                if (!texture.loadFromFile("images/blocks/" + ruta(mapa[x][y]) + ".png"))
                return -1;

                sf::RectangleShape rectCaja(sf::Vector2f(16, 16));
                rectCaja.setPosition(sf::Vector2f(x*16, y*16));
                //rectCaja.setFillColor(sf::Color::Black);
                rectCaja.setTexture(&texture);
                window.draw(rectCaja);
            }
        }
}


Un saludo.

Interesados hablad por Discord.

rir3760

Si todos lo campos tienen la misma longitud no es necesario el separador (la coma), si se elimina el contenido del archivo seria:
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
000000000000000000000000000000
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111
111111111111111111111111111111

Y la lectura del archivo se podría realizar utilizando un vector y un bucle:
Código (cpp) [Seleccionar]
ifstream in;
vector<string> linea;
string aux;

// Apertura del archivo

while (getline(in, aux))
   linea.push_back(aux);
in.close();


Y si se debe almacenar la información en un array de arrays de caracteres la lectura que haces:
Código (cpp) [Seleccionar]
char mapa[worldWidth][worldHeight];
int x = 0, y = 0;
char c;

while(fstr.good())
{
   c = fstr.get();
   if (int(c) != -1 && c!= ',' && c!= '\n') {
       mapa[x][y] = c;
       x++;
   }
   if (c=='\n')
   {
       x = 0;
       y++;
   }
}

Tiene dos errores: almacenar el valor de retorno de get en una variable de tipo char cuando debería ser de tipo int y asumir que el valor de EOF es -1 (lo usual pero no esta garantizado).

Seria mejor cambiar ese fragmento utilizando otra versión de la función get:
Código (cpp) [Seleccionar]
char mapa[worldWidth][worldHeight];
int x = 0, y = 0;
char c;

while (fstr.get(c))
   if (c == '\n'){
      x = 0;
      y++;
   }else if (c != ','){
      mapa[x][y] = c;
      x++;
   }


Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

z3nth10n

Muchisimas gracias rir... xD Está bastante simplificado el code.. :D

Interesados hablad por Discord.