| Ver tema anterior :: Ver siguiente tema | | Autor | Mensaje |
|---|
coto.
Registrado: 16 Ago 2007 Mensajes: 5 Ubicación: mos
| Publicado: 20/09/2007 1:49 am | | | Título: problemas al leer un csv |
| hola
tengo una lista de datos para leer un csv, el csv es tipo esto
12;111 13;112 14;113 15;114 16;115 17;116 18;117 19;118 20;119 21;120 22;121 23;122
bueno pero con mas filas y columnas, y todos con datos enteros.
tengo este codigo:
| Cita: | #include <stdio.h>
main(){
char linea[][]; int n;
const char *filename = "C:\\cima.csv"; FILE *Archi;
Archi = fopen(filename,"r"); // abre el archivo if(Archi==0){ // comprueba si es capaz de abrilo fprintf(stderr,"Fallo al abrir %s \n",filename); }
while(feof(Archi)){
fgets(linea,n,Archi); n++; }
fclose(Archi);
|
la coña como hago con fgets que lea datos enteros y a la vez haga una matriz bidemensional??? gracias de antemano |
| | Volver arriba | |  | polly
Registrado: 19 Jul 2007 Mensajes: 61
| Publicado: 20/09/2007 3:11 am | | | Título: |
| la respuesta no la se , pero creo q hay un pequeño fallo en tu programa , no seria en lugar de while(feof(archi)) while( ! feof(archi)) _________________ R.I.P Kurt Cobain ------------------------- |
| | Volver arriba | |  | coto.
Registrado: 16 Ago 2007 Mensajes: 5 Ubicación: mos
| Publicado: 20/09/2007 3:21 am | | | Título: |
| | sisi error de correr... |
| | Volver arriba | |  | | mamntc02
Registrado: 30 Abr 2007 Mensajes: 242
| Publicado: 20/09/2007 4:45 am | | | Título: |
| Hola,
tienes ciertas cosillas q no están bien. La declaración: es errónea. Un array debe tener, a diferencia de los punteros, unas dimensiones definidas, por ser memoria q ser reserva estáticamente. Se puede omitir el primer campo (o dimensión) al declarar funciones, pero no los demás. A pesar de q puede funcionar esta sentencia tampoco es correcta:Nadie te asegura q NULL esté definido como 0, de hecho ni siquiera es cierto, pq muchos compiladores lo definen como 0L, o como (void *) 0, por tanto usa mejor NULL. También sería correcto: Respecto a como recuperar los datos no creo q se pueda hacer directamente, sino q lo vas a tener q hacer a mano, por ejemplo:
| Código: | int guardaLinea(int **matrizDatos, char *linea, int row){
int pos = 0; char cadena[20] = {0};
while(*(++linea) != ';') pos++; // Buscamos el ';'
memcpy(cadena, linea, pos); //copiamos el primer valor en cadena matrizDatos[row][0] = atoi(cadena); // Convertimos a entero
memset(cadena, 0x0, sizeof(char) * 20); memcpy(cadena, &linea[pos], strlen(linea)); //copiamos el segundo valor en cadena matrizDatos[row][1] = atoi(cadena); // Convertimos a entero return 0; }
|
Tu código quedaría más o menos:
| Código: | int matrizDatos[M][2]; char linea[100] = {0}; ... n = 0; while(feof(Archi)){
fgets(linea,100,Archi); guardaLinea(matrizDatos, linea, n); n++; }
|
No he probado q esté bien sólo es orientativo, por lo q es muy posible q tengas q hacer algún cambio.
Saludos. |
| | Volver arriba | |  | DCelso

Registrado: 28 Abr 2004 Mensajes: 112
| Publicado: 20/09/2007 7:00 am | | | Título: |
| Para poder hacerlo totalmente dinámico deberás recorrer dos veces el archivo. Una vez para calcular el número máximo de filas y columnas y poder crear la memoria dinámica necesaria. Y otra vez para leer los datos e insertarlos en la matriz.
Otra opcion sería crear un arreglo TDA enlazado e ir uno a uno creando memorioa e insertando. Pero esto acomplejaría el código. |
| | Volver arriba | |  | rir3760

Registrado: 01 Oct 2004 Mensajes: 3657 Ubicación: Mexico
| Publicado: 20/09/2007 7:05 am | | | Título: |
| | coto. escribió: | tengo una lista de datos para leer un csv, el csv es tipo esto
12;111 13;112 [...]
bueno pero con mas filas y columnas, y todos con datos enteros. [...] la coña como hago con fgets que lea datos enteros y a la vez haga una matriz bidemensional |
Lo mas importante aqui es que aclares la estructura de cada linea de texto indicando si todos los campos estan separados (excepto el ultimo) por el caracter ';', por ejemplo:
| Código: | 12;111 12;11112;11112;11113;112 12;11112;111 12;11112;11112;111 ... |
O estos son pares separados en una linea por algun otro delimitador, por ejemplo espacio blanco:
| Código: | 12;111 12;111 12;111 12;111 12;111 12;111 12;111 12;111 12;111 ... |
En cuanto al uso en C de la constante 0 en el contexto de punteros:
| Código: | if(Archi == 0){ fprintf(stderr,"Fallo al abrir %s \n",filename); } |
Es valido ya que en este contexto el uso de la constante resulta en una "null pointer constant". Sin embargo no es politicamente correcto y se prefiere el uso de la macro NULL debido a que esta es mas explicita.
Y para la verificacion de errores es mejor dejar que el mensaje de error se genere de forma automatica mediante la funcion perror:
| Código: | if(Archi == NULL){ perror(filename); return EXIT_FAILURE; } |
Por ultimo no es correcto el uso de feof para controlar el bucle ya que se realizaria una iteracion de mas, esto se debe a que la funcion feof solo retorna el valor verdadero despues de que una funcion de lectura trata de leer datos y falla.
En su lugar y si se va a utilizar fgets lo mejor es utilizar el valor de retorno de esta funcion directamente:
| Código: | while (fgets(linea, LONG_LINEA, Archi) != NULL){ /* proceso de linea */ } if (ferror(Archi)){ /* manejo de error */ }
/* ... */ |
Un saludo _________________ The capacity to learn is a gift; The ability to learn is a skill; The willingness to learn is a choice. -- Rebec of Ginaz |
| | Volver arriba | |  | | coto.
Registrado: 16 Ago 2007 Mensajes: 5 Ubicación: mos
| Publicado: 20/09/2007 3:10 pm | | | Título: |
| ahora tengo esto tal que asi y mis dudas:
| Cita: | #include <stdio.h> #include <stdlib.h> #include <mem.h> #include <string.h>
int guardaLinea(int **matrizDatos, char *linea, int row);
main(){
int matrizDatos[M][2]; char linea[100000] = {0};
int n=0;
const char *filename = "C:\\cima.csv"; FILE *Archi;
Archi = fopen(filename,"r"); // abre el archivo if(Archi==NULL){ // comprueba si es capaz de abrilo fprintf(stderr,"Fallo al abrir %s \n",filename); }
while(!feof(Archi)){
fgets(linea,100,Archi); guardaLinea(matrizDatos, linea, n); n++; }
fclose(Archi);
}
int guardaLinea(int **matrizDatos, char *linea, int row){
int pos = 0; char cadena[100000] = {0};
while(*(++linea) != ';') pos++; // Buscamos el ';'
memcpy(cadena, linea, pos); //copiamos el primer valor en cadena matrizDatos[row][0] = atoi(cadena); // Convertimos a entero
memset(cadena, 0x0, sizeof(char) * 20); memcpy(cadena, &linea[pos], strlen(linea)); //copiamos el segundo valor en cadena matrizDatos[row][1] = atoi(cadena); // Convertimos a entero
return 0; }
|
| Cita: | | int matrizDatos[M][2]; |
que tiene que ver esa M hay en el medio... no lo cojo por mucho que lo intente.
leugo me da los siguientes erroes al compilar que no doy solucionado a ver quien me ayuda
| Cita: | Info :Compiling C:\BC5\BIN\noname00.cpp Error: noname00.cpp(12,19):Undefined symbol 'M' Error: noname00.cpp(27,3 :Cannot convert 'int ( *)[2]' to 'int * *' Error: noname00.cpp(27,3 :Type mismatch in parameter 'matrizDatos' in call to 'guardaLinea(int * *,char *,int)' Warn : noname00.cpp(33,2):'matrizDatos' is declared but never used
|
y de ahi no salgo.. ayuda por favor |
| | Volver arriba | |  | DCelso

Registrado: 28 Abr 2004 Mensajes: 112
| Publicado: 20/09/2007 4:59 pm | | | Título: |
| Por lo que comentas parece que no te has leido ningún tutorial, libro, apuntes de C. No se puede programar C sin saber C.
En principio M al estar dentro de unos corchetes en la declaración de una variable te da muchas pistas de qué debe de ser. Debe ser un número y además es una de las dimensiones de la matriz declarada. Si char a[2][3] define una matriz de 2 columnas y 3 filas pues entonces si ponemos M será de M filas. Puesto que en la declaración solo pueden ponerse números, nunca se puede usar variables solo te deja la opcion de que es una macro que sirve para identificar un valor a través de un conjunto de palabras más ameno para la lectura del codificador. #define M 3
El siguiente error es también lógico, no le estás pasando de entrada a la función el mismo tipo de dato con que la declaraste. Asi que en la declaración de la funcion pon int *matrizDatos[2]
Para más información leete el libro de C de clase, sino va a ser imposible que puedas seguir programando ya que a cada pregunta que hagas te tendría que remitir a varias páginas de teoría del libro y no acabaríamos nunca.
Venga suerte, y al toro. |
| | Volver arriba | |  | coto.
Registrado: 16 Ago 2007 Mensajes: 5 Ubicación: mos
| Publicado: 21/09/2007 1:39 am | | | Título: |
| hola
lo de m me lo imaginaba pero nuestro profesor nos decia que los define eran inutiles y que no merecia la pena usarlos...:S solo lo usabamos para el #define Pi 3.1415
eso esta entendido ahora lo del otro dato no lo entiendo, los punteros siempre fue una asignatura pendiente que poco a poco intento aprender.
libros de c tengo una de anaya que me aclara muchas dudas.. pero no todas como yo quisiera.
un saludo |
| | Volver arriba | |  | | cheroky
Registrado: 22 Sep 2005 Mensajes: 1372 Ubicación: En ecx esperando un call
| Publicado: 21/09/2007 1:47 am | | | Título: |
| | coto. escribió: | hola
lo de m me lo imaginaba pero nuestro profesor nos decia que los define eran inutiles y que no merecia la pena usarlos...:S solo lo usabamos para el #define Pi 3.1415 |
Hay una macro M_PI con el valor de pi en doble precision, definida en el header math.h
S2. _________________ - Explícito es mejor que implícito. - Simple es mejor que complejo. - Complejo es mejor que complicado. - Plano es mejor que anidado. - Ralo es mejor que denso. |
| | Volver arriba | |  | mamntc02
Registrado: 30 Abr 2007 Mensajes: 242
| Publicado: 21/09/2007 4:49 am | | | Título: |
| Hola,
en mi humilde opinión es mejor usar constantes q #defines por infinitas razones, pero tampoco soy un talibán contra los #defines, como otros Es decir:
| Código: | //En lugar de: #define PI 3.1416 //Es mejor usar const double PI = 3.1416;
|
Algunas de las razones las podeis encontrar en: parashift (en inglés)
Saludos. |
| | Volver arriba | |  | cheroky
Registrado: 22 Sep 2005 Mensajes: 1372 Ubicación: En ecx esperando un call
| Publicado: 21/09/2007 5:26 am | | | Título: |
| Tampoco quiero sentar catedra, pero personalmente las trato de forma diferente simplemente por que son diferentes. Las macros de literales solo tienen R-value y se resuelven en fase de diseño, su naturaleza es espandirse alla donde haya un identificador con su nombre. Su ventaja es la eficiencia. En cambio las variables constantes si tienen L-value, incluso en C pueden modificarse en runtime, no asi en C++, pero esto es debido a que son definidas como read-only pasando a una ubicacion de solo lectura y provocando una excepcion si se intenta sobreescribir, algo parecido a los literales de cadena.
S2. _________________ - Explícito es mejor que implícito. - Simple es mejor que complejo. - Complejo es mejor que complicado. - Plano es mejor que anidado. - Ralo es mejor que denso. |
| | Volver arriba | |  | | rir3760

Registrado: 01 Oct 2004 Mensajes: 3657 Ubicación: Mexico
| Publicado: 21/09/2007 7:22 am | | | Título: |
| | coto. escribió: | | ahora tengo esto tal que asi y mis dudas |
No quiero sonar como un profesor regañon pero simplemente ignoraste lo que te comente y que es fundamental para poder ayudarte: la estructura exacta del archivo de datos, sin esta no es posible desarrollar una solucion que te sea satisfactoria.
Y si vas a programar utilizando el paradigma de programacion estructurada en C++ deberias seguir las indicaciones que ya te dimos como no utilizar feof para controlar la lectura de un archivo.
En lo que respecta al uso o no de constantes simbolicas (macros vs const) esto depende del lenguaje: en C no hay (salvo el uso de enums) otra forma de definir constantes (como ya comento Cheroky en C la palabra reservada "const" NO define constantes) mientras que en C++ "const" si lo hace y por eso se prefiere su uso sobre las macros ("macros are evil" segun el propio autor y la FAQ de comp.lang.c++).
Casi lo olvido: la lectura de un buen libro sobre punteros donde se expliquen las diferencias entre arrays y punteros es necesaria ya que la funcion "guardaLinea" espera un "char **" y tu le estas pasando un "int (*)[2]". Un libro que pone enfasis en el tema de los punteros es:
Pointers on C, 1st edition Kenneth Reek Addison Wesley, July 25, 1997 ISBN: 0673999866
Un saludo _________________ The capacity to learn is a gift; The ability to learn is a skill; The willingness to learn is a choice. -- Rebec of Ginaz |
| | Volver arriba | |  | | |
| No puede crear mensajes No puede responder temas No puede editar sus mensajes No puede borrar sus mensajes No puede votar en encuestas
|
|
| |