Ayuda con manejo de ficheros en c++

Iniciado por ArashiTensei, 22 Noviembre 2014, 05:41 AM

0 Miembros y 2 Visitantes están viendo este tema.

ArashiTensei

Necesito ayuda con el manejo de archivosde texto  en c++

tengo muchos datos en un archivo, son puros numeros, y tienen esta estructura

***********
*********
*******
*****
***
*

*
**
********

la primeras hasta el antepenultimo numero va en un arreglo , o eso pretendo, y los ultimos numeros de cada fila en otro vector, el problema es que entre los numeros hay espacios y estos no son constantes, ademas de que hay numeros de mas de 1 digito, entonces no puedo usar fgetc , y con fgets no se como separar los numeros de los espacios... agluein conoce alguna forma?

engel lex

El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

ArashiTensei

de echo uso el getline pero aun no tengo la practica con estas funciones , eh podido imprimir la diagonal , alrevez pero aun no tengo muy claro como lo eh echo :(

Código (cpp) [Seleccionar]
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdlib.h>
#include <stdio.h>


using namespace std;

int main(){
    string linea;
    int numero,i=0;
    int vector[100];
    int temp;
    ifstream F_in;
    F_in.open("1.txt");
    int cap = 699;
    while (getline (F_in, linea)){
        istringstream S(linea);
while (S >> numero){
   for(int i=0;i<100;i++)
vector[i] = numero;
        }
printf  ("%i\n",vector[i]);

}
    F_in.close();
}

Orubatosu

Creo que el problema principal, es que no nos has explicado detalladamente que pretendes hacer.

Entiendo, que tienes un fichero de texto "1.txt", y que este contiene números separados por uno o mas espacios en cada línea

Luego, veo que declaras "i" a cero, lo cual es irrelevante si luego la declaras de nuevo en el bucle for, pero vamos, eso no tiene importancia, lo mismo que el de la variable Temp que tampoco le veo uso, o "cap". Asumo que les das uso mas adelante.

Lo que si que veo, es que abres fichero... correcto. Coges una línea entera del fichero, y la almacenas en el string linea. Correcto... creas un objeto istringstream con ella, y haces un while para sacar todos los números que contiene

Lo que "no entiendo", es porque una vez tienes un numero, lo introduces a continuación en todas las posiciones del entero "vector", y luego tras el while imprimes únicamente un valor de ese array de enteros.

Creo que por ahí está tu problema. Cuando llegas al bucle


for(int i=0;i<100;i++) vector[i] = numero;


Lo que estás haciendo es introducir en cada vuelta del while (S >> numero) el entero que sacas del objeto S en todas y cada una de las casillas de vector

Finalmente tras el while, imprimes un solo valor. Si interpreto bien tu codigo,lo que haces es imprimir el último entero que obtienes de cada linea, ya que en cada vuelta del while (S >> numero) coges ese valor y lo pones en todas.

No se si me estoy explicando bien, pero es que tampoco tengo muy claro que pretendes hacer exactamente con los números que obtienes del fichero.
"When People called me freak, i close my eyes and laughed, because they are blinded to happiness"
Hideto Matsumoto 1964-1998

ArashiTensei

Lo has interpretado muy bien, es exactamente lo que hace, hay varias cosas que no uso en este codigo que puse antes y se debe a que eh estado modificandolo para exprimentar los resultados, se me olvido borrarlos.

Explicare mejor que es lo que pretendo.

Tengo un archivo 1.txt es una instancia de valores sobre el problema de la mochila cuadratica, lo que necesito es obtener esos valores en una matriz para manipularlos y debe ser de la siguiente forma

La primer fila hasta la fila es el nombre del archivo
la segunda es el numero de objetos (100)
la tercer fila con los valores combinados de beneficio que tiene cada objeto, como ejemplo pongo lo siguiente para representarlo:  Los números del 1 al 6 no están en el archivo los pongo para que se entienda de que las coordenadas donde apuntan los números son la combinación de de 2 objetos lo que lo hace un beneficio combinado

nombre del la instancia
100   //  cantidad de objetos
   1 2 3 4 5 6.. 100        La diagonal son los beneficios individuales
1 0 4 5 7 8 3        los demas son beneficios combinados
2    0 5 6 7 7
3       7 4 2 7
4          3 4 1
5             2 9
6                5

capacidad de la mochila
pesos  *  *  *  *  *  * ... 100
pero en el archivo no viene de esta forma sino como la que puse al principio.
quiero que eceptuando el ultimo numero guarde todos los numeros en la primer fila de una matriz , la segunda fila en la segunda fila de la matriz, y asi sucesivamente, la diagonal la guarda en otro vector y el peso que es la ultima fila  en otro vector.

El codigo que puse no es mio, estuve investigando la forma de hacer el problema y vi un ejemplo que me ayudaba , pero no entiendo todavia como manejar estas sintaxis, donde pone el while (S >> numero)  .. aparte de que no conozco ese operador, me supongo que es lo que permite que los numeros sean identificados en sus dos digitos y no solo un digito como estaba antes con el fgetc, pero no entiendo en que parte del archivo hace el bucle, es hasta encontrar un salto de linea? o la comparacion la hace cada que encuentra un numero?
me estoy frustrando demasiado ya que el programa debe hacer muchas cosas mas con los datos del archivo y aun no puedo ni obtener los datos... espero que ahora si se entienda un poco mejor, saludos y gracias por responder!

Orubatosu

Debería de echarle un vistazo con mas detenimiento, pero te aclaro algunas cosas.


(S >> numero)


¿Que hace esta línea?... veamos, debemos de irnos antes a la creación del objeto S

istringstream S(linea);

Anteriormente, hemos usado Getline, que es una función que coge toda una cadena de texto, incluyendo espacios (hasta el caracter de retorno de carro, el que indica que termina la línea) y lo mete en la variable string linea.

Linea acepta una cantidad de caracteres arbitraria, no necesitamos en principio conocer su tamaño, ni lo que contiene, de manera que estamos seguros de que ha leido una línea entera del fichero de texto.

Pero, como bien has dicho, lo que queremos leer son enteros, no un string. Si tenemos un string y sabemos que los números están separados por espacios, podemos "currarnos" una función que se dedique a buscar los espacios, identifique lo que son numeros, y construya numeros a partir de la misma, pero no nos hace falta, porque tenemos el istringstream

Esta clase, permite meter un string "linea" en un objeto, y aunque a priori nos puede parecer que "es un string con otro nombre" en realidad es mucho mas, se comporta como un dispositivo de entrada (o de salida, o ambos, pero ese es otro tema)

Y ahora llegamos a la línea que te tiene "escamado"


while (S >> numero);


Estos operadores, los ">>" y "<<" indican la dirección desde donde, o hacia donde fluye la información entre un contenedor y las instrucciones que usan esos datos.

Un ejemplo, es el comando CIN o COUT de C++, que permiten leer desde el teclado o sacar cosas por pantalla.

Tu usas "printf  ("%i\n",vector);", pero podemos usar perfectamente:

cout << "lo que queremos sacar" << vector << "cualquier otra cosa";

Las flechas indican que las cadenas de texto, la variable o cualquier otra cosa va desde ahi, hasta el cout, que las saca por pantalla en consola.

Así pues:

while (S >> numero)

Quiere decir "mientras podamos sacar números enteros (la variable numero es un entero) del objeto S". Al mismo tiempo, asigna a esa variable a cada pasada un nuevo valor que lee del objeto S (siempre que sea un entero)

El bucle se mantendrá mientras podamos sacar enteros de ese objeto, cuando llegue al final de mismo y no se pueda sacar ninguno mas, simplemente la condición será false, y por lo tanto saldrá del bucle.

Al margen de todo esto, te recomiendo no llames "vector" a lo que es un array. Una variable como "int vector[100];" es perfectamente válida, pero puede dar lugar a malinterpretaciones y te puede incluso liar a ti mismo si consideras un array como un vector, ya que C++ tiene precisamente un tipo de array especial llamado "vector" que permite redimensionar la cantidad que almacena.

Tal que asi

vector <int> Nombre[100];

Con la particularidad de que puedes incluso declararlo vacio, y rellenarlo con los datos que estimes conveniente, ajustándose su tamaño a los datos que introduzcas. Supongo que aún no has llegado a esa parte

Un detalle que no entiendo muy bien, ¿porque en el fichero te indica el número de objetos a leer, si en realidad ya lo conoces de antemano?

De todos modos, creo que deberías de hacer dos "getline" antes de empezar la lectura del fichero, uno para separar el nombre de la instacia (y manejarlo como quieras) y otro para la segunda linea, y a partir de ahi tratar los datos que entran.

No se si te sería quizás mas claro usar un array de dos dimensiones si conoces de antemano el tamaño del mismo, algo como int nombre[10][10]; para una matriz de 10 elementos por 10 elementos

"When People called me freak, i close my eyes and laughed, because they are blinded to happiness"
Hideto Matsumoto 1964-1998

ArashiTensei

#6
Primero gracias por la ayuda,  ahora puedo entender como funciona, tenia la corazonada de que >> era sobre el uso de CIN y COUT, pero tampoco es que supiera que es a lo que se referían estos símbolos.
Lo de la variable vector, en realidad tengo pensado cambiarle el nombre, le puse vector por la costumbre, pero no sabia que era una palabra reservada, gracias por le dato.

Sobre lo que no entendías en el archivo,  viene la cantidad de objetos porque no es la única instancia de la que debo obtener datos, hoy otras con datos de objetos de hasta 300, tengo pensado obtener este numero (100) en una variable que identifique la cantidad de objetos para poder modificar los arrays que contendrán los datos de los objetos y no tener que hacer código para cada instancia.
Bueno, te agradezco la ayuda, con esta informacion veré que puedo avanzar, saludos!




Gracias a lo que me explicaste ya eh podido  obtener los datos mas facilmente, la primera fila me da algo raro, la segunda ya la tengo y en la tercera, según yo almaceno todos los datos en la matriz, pero extrañamente me quedan corridos un espacio menos:

en la tercer fila me empieza este problema, los datos obtenidos son mostrados menos el primero:

#include <iostream>
#include <fstream>
#include <sstream>
#include <stdlib.h>
#include <stdio.h>


using namespace std;

int main(){
    string linea;
    int numero,num,i=0,j=0,cantidad;
    int Matriz[100][100];
    ifstream F_in;
    F_in.open("1.txt");
   
getline (F_in, linea);
getline (F_in, linea);
istringstream S1(linea);
while(S1 >> numero){
cantidad = numero;
printf("%i\n\n",cantidad);
}


while(getline (F_in, linea)){
istringstream S2(linea);
while (S2 >> numero){
if( i == 100){
i=0;j++;
}
Matriz[i][j] = numero;i++;
}

}

for(int i=0; i<100;i++)
printf("%i.- [%i]\n",i+1,Matriz[i][2]);
    F_in.close();
}



Orubatosu

Si pudieras pegar un trozo del archivo a procesar sería probablemente mas fácil entender lo que quieres hacer exactamente, y se podrían hacer algunas pruebas.

Se puede ademas reducir un poco el código, pero si así te aclaras está bien
"When People called me freak, i close my eyes and laughed, because they are blinded to happiness"
Hideto Matsumoto 1964-1998

ArashiTensei

Jaja si, se que el código no es nada elegante, pero creo que así entiendo lo que hago mejor, la practica me hará mejorar, supongo.

Aqui te dejo el archivo para que veas como esta estructurado, te recomiendo abrirlo con notepad++, porque al abrirlo en el notepad normal sale una sola linea
https://mega.co.nz/#!whRT0I7K!Ysx_szFA7ovtuPr-LVAUmVfG-k6PD4vccKX9UR9AdKg

yo le cambie el nombre al archivo por eso puse "1" en el código.