Test Foro de elhacker.net SMF 2.1

Programación => Programación C/C++ => Mensaje iniciado por: z3nth10n en 19 Septiembre 2013, 20:13 PM

Título: Hacer array de 2D a través del split de una string con un delimitador
Publicado por: z3nth10n en 19 Septiembre 2013, 20:13 PM
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
Título: Re: Hacer array de 2D a través del split de una string con un delimitador
Publicado por: 0xDani en 19 Septiembre 2013, 20:56 PM
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;
}
Título: Re: Hacer array de 2D a través del split de una string con un delimitador
Publicado por: z3nth10n en 20 Septiembre 2013, 15:06 PM
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... :/

(http://gyazo.com/30b4ea2999c9d0e4be6681ccccb166af.png)




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
Título: Re: Hacer array de 2D a través del split de una string con un delimitador
Publicado por: 0xDani en 22 Septiembre 2013, 15:02 PM
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.
Título: Re: Hacer array de 2D a través del split de una string con un delimitador
Publicado por: z3nth10n en 22 Septiembre 2013, 16:49 PM
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.
Título: Re: Hacer array de 2D a través del split de una string con un delimitador
Publicado por: rir3760 en 22 Septiembre 2013, 18:18 PM
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
Título: Re: Hacer array de 2D a través del split de una string con un delimitador
Publicado por: z3nth10n en 22 Septiembre 2013, 18:26 PM
Muchisimas gracias rir... xD Está bastante simplificado el code.. :D