PDA

Ver la versión completa : Ayuda con una pequeña duda sencilla de programación en C!



IsaacMG
25/03/2012, 19:51
LO HE CONSEGUIDO (más información en mi último post (aunque todavía necesito una ayudita))

EDIT: HOLA, hoy es 31 de mayo del 2012.

Vuelvo a la carga con otra de mis sencillas dudas de programación, por cierto, gracias a todos los que contestáteis últimos y no os dí las gracias, lo hago ahora, me ayudásteis MIL, os lo pagaría pero soy pobre... así que espero que el hecho de ver a alguien aprender gracias a vosotros os sirva como recompensa :D

En fín, tengo otra duda... tengo que hacer un programilla que abra un fichero TXT y me presente todos los EMAILS que haya dentro... es decir, será un TXT con mucho texto y por medio habrán emails sueltos, y el programa tendrá que coger esos emails y presentarme solo eso.

Hasta ahora he encontrado, buscando por internet cómo no (como dije, mi profesor no explica NADA, solo da pistas, y tengo que apañarmelas para encontrar las cosas hechas o a medio hacer y entenderlas y terminarlas)

En conclusión, tengo esto:


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

int main()
{
FILE *archivo;
char caracter;

archivo = fopen("prueba.txt","r");

if (archivo == NULL){

printf("\nError de apertura del archivo. \n\n");
}else{


printf("\nEl contenido del archivo de prueba es: \n\n");

while (feof(archivo) == 0)
{
caracter = fgetc(archivo);
printf("%c",caracter);
}
}
fclose(archivo);
return 0;
}

Lo que hace es abrirme un TXT y presentarme todo el texto que tiene dentro.

A ver si me podéis dar unas pistas sobre como comenzar para que me busque emails en el texto y me presente solo esos mails.

Luego, otra duda... es muy difícil hacer que el programa mire en la carpeta dónde se ejecuta y, en el caso de que haya más de un txt, me de opción a escoger el que quiera de ellos? (esto no lo piden, pero me gustaría aprender a hacerlo). Lo que es hacer un menú sencillito para escoger distintas funciones en un programa lo he hecho, pero eso de escanear una carpeta para encontrar ficheros ni lo hemos tocado, y no creo que lo toquemos en clase (triste pero es así).

En fín, a ver si aparecen por aquí de nuevo los gurús del foro, cracks! (qué pelota) jaja

-------------------------------------------------------------------------------------------------------------------
POST VIEJO

Hola, veréis, soy novato en programación, y esta tarde se me ha encallado un pequeño programa que estaba haciendo, una cosa sencilla, pero no sé por qué me peta... veamos, la función es que yo le inserto un string de carácteres, luego le inserto otro, luego le inserto un número que indicará una posición, y el objetivo es que me inserte el segundo string de carácteres en el primero, a partir de la posición que le he indicado. Ahí va:


void unirposicion(){


char * strA[128];
char * strB[64];
char * strC[256];
char cadena [512];
int aux;
int x;

strcpy(cadena,"Introduce una cadena: ");
pinta(cadena);
aux=scanf("%s",&strA);

strcpy(cadena,"Introduce otra cadena: ");
pinta(cadena);
aux=scanf("%s",&strB);

strcpy (cadena,"Introduce la posicion: ");
pinta(cadena);
aux=scanf("%s",x);

strncpy(strC,strA,x);
strC[x] = '\0';
strcat(strC,strB);
strcat(strC,strA+x);
printf("%s\n",strC);

}

Cuando le asigno un número que sería la posición, el programa peta. En vez de eso, si ya le asigno un número predeterminado a 'x' (int x=5), me hace lo que quiero, pero claro, me pega el segundo string en el primero a partir de la posición 5 (o el número que sea).

En qué estoy metiendo la pateja? Gracias!

No os riais, que soy muuuuuuy novato... :p

EDIT: no uso el printf porque el objetivo del programa es que no se use el printf en ningún momento, por eso lo hago a través de copiar y pegar el contenido en un string con la función:

int pinta (char *cadena){
printf("%s",cadena);

juanvvc
25/03/2012, 20:06
A la función scanf no tienes que pasarle el valor de x (que además cuando la llamas aún está indefinido) sino su dirección, para que scanf() sepa dónde tiene que guardar la entrada del usuario. Además, x es un entero y estás preguntando por un número entero, así que su tipo es %d y no %s.

El código correcto de esa línea es:


aux=scanf("%d",&x);

sereno
25/03/2012, 20:06
En aux=scanf("%s",x); estas leyendo un string en lugar de un entero, no?

juanvvc
25/03/2012, 20:08
Y ya que estamos, no entiendo cómo declaras strA, strB y strC. Deberían ser:



char strA[128];
char strB[64];
char strC[256];
char cadena [512];

IsaacMG
25/03/2012, 20:20
Yay! Esos eran justo los fallos, ahora funciona perfecto!

MIL gracias a ambos, de corazón!

juanvvc, ya he dicho que soy muuuuuuuuy novato, y el profesor que tenemos es bastante... bueno, poco competente, hay cosas que las explica mal, y la verdad es que en toda la clase estamos bastante cabreados, prácticamente estoy aprendiendo la programación por mi propia cuenta y no por lo que (no) explica el profesor.

En fin muchísimas gracias de nuevo :)

IsaacMG
26/03/2012, 03:44
Ok... tengo otro problema, que había solucionado y que sin tocar nada, misteriosamente, vuelve a no funcionar...



char * cadena;
char * cadena1;
char str[32];
int aux;
int num;

strcpy(cadena, "Introduce un caracter: ");
pinta(cadena);
aux=scanf("%s",&cadena1);

strcpy (cadena,"Introduce el numero de repeticiones: ");
pinta(cadena);
aux=scanf("%d",&num);

memset (str,cadena1,num);

strcpy(cadena,str);
pinta(cadena);

La función es rellenar un string "str" con un carácter "cadena1" un cierto número de veces "num". Por alguna razón, después de introducir el carácter el programa me da un error y acaba. De verdad que flipo porque hace un rato me funcionaba, lo he probado dos o tres veces y iba correctamente, y ahora no funciona... a ver si me echáis una mano!

juanvvc
26/03/2012, 04:39
Tal como lo has escrito, cadena y cadena1 son punteros a memoria... sin reservar. Cuando haces strcpy(cadena, "Introduce un caracter: ");, esa cadena se está copiando a un trozo absolutamente aleatorio de memoria. Si en esa memoria no hay nada, suertudo, pues funciona. Si esa memoria no es accesible/se está usando para otras cosa, casca. Depende de la suerte, por eso "a veces funciona y a veces no" y en realidad lo normal es que NO funcione.

Dos opciones:

1.- Opción 1: reservas la memoria "al compilar". Es decir, que hay algunos bytes dentro de tu archivo EXE que servirán para guardar lo que quieras meter en cadena y cadena1. Eso se hace reservándoles espacio igual que has hecho con la cadena str:



char cadena[32];
char cadena1[32];
char str[32];


Opción 2: reservas la memoria cuando ejecutas. Tu archivo EXE es más pequeño, pero tienes que recordar reservar la meoria al ejecutar.



char * cadena;
char * cadena1;
char str[32];

cadena = (char *) malloc(sizeof(char) * 32);
cadena1 = (char *)malloc(sizeof(char) * 32);


(En realidad, después de reservar tendrías que comprobar que cadena y cadena1 no son cero (0), porque entonces es que no ha podido reservar la memoria, la has gastado toda con el vídeo de youporn)

Con cadenas tan pequeñas da igual que reserves el compilar o al ejecutar, pero imagina que estás haciendo un juego con cientos de gráficos y varios gigas: esa memoria, obligatoriamente, tendrás que reservarla al ejecutar. Si la reservas al compilar, ¡tu EXE tendría un tamaño de un giga y tardaría la vida en cargarse!

DarkDijkstra
26/03/2012, 09:28
Sólo como puntilla, si reservas la memoria dinámicamente (o como bien dice juanvc, "al ejecutar"), recuerda que antes de que termine la ejecución de tu programa, tienes que liberarla

free(cadena);
free(cadena1);

o de cara al sistema operativo, esa memoria seguiría "reservada"... de nuevo lo mismo, si son un par de cadenas pequeñas da igual (aunque todo buen programador debería liberar toda su memoria) pero en cuanto se trate de "mucha" memoria, podría tumbarte el sistema aunque no tuvieses ningún programa en ejecución ; )

hardyx
26/03/2012, 10:06
Tienes que reservar memoria para las cadenas, lo más fácil, ya que estás empezando es usar cadenas estáticas: char cadena[longitud]; Luego, para leer cadenas, en vez de scanf("%s",cad), también puedes usar gets(cadena), que es una función que leer una cadena hasta el retorno de carro. Y otra cosa importante, recuerda que las cadenas (y los arrays en general) en C son punteros, por lo tanto si usas scanf("%s", cadena), no tienes que poner el &. Sino, estarías usando un puntero doble. Cuidado con eso.

Eskema
26/03/2012, 10:08
(En realidad, después de reservar tendrías que comprobar que cadena y cadena1 no son cero (0), porque entonces es que no ha podido reservar la memoria, la has gastado toda con el vídeo de youporn)

Y dios hizo la luz!!!!, joer ahora se porque mis juegos petaban, gasto toda la memoria con youporn y luego el juego no va. Me has abierto los ojos!!!!
[IRONIC MODO OFF]

IsaacMG
31/05/2012, 14:31
Arriba, que tengo otra duda!

efegea
31/05/2012, 14:40
Define "email".

¿Direcciones de email? ¿Mensajes completos con todas sus cabeceras? ¿Qué separación hay entre cada uno de ellos?

IsaacMG
31/05/2012, 14:50
Direcciones de email, perdón. O sea, por ejemplo tendré un texto:

"Manolito es tonto, le gusta correr y su email es manolito@tontico.com
Pepe tiene email y es pepe@pepe.com "

El texto tendré que crearlo yo, separación pues un espacio blanco detrás y otro delante del mail.

No pido que se me resuelva el ejercicio eh, que eso es tener cara, solo quiero saber cómo empezarlo :p

juanvvc
31/05/2012, 14:52
¿Cuál es la pregunta? :confused:

efegea
31/05/2012, 15:00
¿El texto de Manolito es el que contiene el txt que vas a leer o el que tienes que generar?

IsaacMG
31/05/2012, 15:01
A ver, que me explico fatal.

El texto de "manolito" es el que estará dentro del archivo txt que por ahora se llama "prueba.txt". Tengo que hacer que mi programa abra ese texto (hecho), y que busque en él todos los emails que haya dentro "blabla@blabla.com" y me imprima (en pantalla!) estos mails, pero que sólo me imprima eso y ninguna otra parte del texto.

La pregunta es: ¿por dónde empiezo? estoy perdidísimo :(

NO TENGO QUE GENERAR NINGÚN TEXTO jajaja que me he explicado fatal ahora que me leo... me refería que el TXT lo rellenaré yo a mano con texto y emails, pero no que el programa me tenga que rellenar nada, el programa solo tiene que coger ese txt y presentarme las direcciones de mail que haya dentro :p

^MiSaTo^
31/05/2012, 15:05
Yo leería el fichero y usaría regexp para detectar los mails ;)

Jurk
31/05/2012, 15:16
Strtok es una funcion que se encuentra en
String.h

Te separa textos por tokens. En este caso. Espacios y entonces solamente deberias de buscar el caracter@ en cada una de las cadenas que te devuelve

---------- Post añadido a las 13:16 ---------- Post anterior a las 13:06 ----------

Puede que te de falsos positivos pero es un buen inicio

^MiSaTo^
31/05/2012, 15:22
Strtok es una funcion que se encuentra en
String.h

Te separa textos por tokens. En este caso. Espacios y entonces solamente deberias de buscar el caracter@ en cada una de las cadenas que te devuelve

---------- Post añadido a las 13:16 ---------- Post anterior a las 13:06 ----------

Puede que te de falsos positivos pero es un buen inicio

Expresiones regulares, o regexp ;)

Jurk
31/05/2012, 15:27
Tambien

"%[]^@%s",&texto1,&texto2

No? Estoy en el curro y no tengo elpc para probar

^MiSaTo^
31/05/2012, 15:32
No lo se porque ahora mismo estoy currando yo tb, y no recuerdo cómo iban las regexp en C.
Pero vamos para mails con usar esto que sale aqui (http://www.regular-expressions.info/regexbuddy/email.html), vale. Ya digo en C no se cómo se usan ahora mismo las regexp pero no puede ser muy distinto a otros lenguajes ;)

IsaacMG
31/05/2012, 15:42
Vaya, gracias por las respuestas :D

Estoy probando con el Strtok y de momento no he conseguido nada.

Misato, el regexp por lo que veo se necesitan librerias externas o algo así para hacerlo en c, ¿no? la cosa es que nos piden hacerlo con las librerías básicas...

IsaacMG
02/06/2012, 22:57
Nada, no logro lo que quiero con el strtok... qué verde estoy en el tema... ¡¡¡¡¡¡¡¡¡¡ayuda!!!!!!!!!!!

Jurk
02/06/2012, 23:22
http://www.cplusplus.com/reference/clibrary/cstring/strtok/

tienes un ejemplo funcional en esa pagina

y aunque al princiopio el puntero debe apuntar al texto, luego debe apuntar a NULL, eh?




/* strtok example
*/
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{

printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}

saca esto:


Splitting string "- This, a sample string." into tokens:
This
a
sample
string

la funcion strpbrk puede serte util para buscar si la cadena lleva @

IsaacMG
03/06/2012, 15:59
Es que no veo la forma en la que pueda conseguir lo que quiero hacer con eso que me comentas Jurk... como ves estoy muy verde en el tema. Estoy intentando todo lo que sé y nada, a ver si dentro de un rato consigo algo que se acerque y pego aquí el código, pero vamos, estoy jodido... D:

Jurk
03/06/2012, 16:16
Pues yo no te voy a ayudar a partir de este punto. Doy clases de informatica y programacion y tengo TOTALMENTE claro que la gente no aprende porque no se ha dado lo suficientes ostias contra la pared. Te puedo decir donde buscar, pero la conciencia me impide darte la solucion.

swapd0
03/06/2012, 18:36
Pues yo no te voy a ayudar a partir de este punto. Doy clases de informatica y programacion y tengo TOTALMENTE claro que la gente no aprende porque no se ha dado lo suficientes ostias contra la pared. Te puedo decir donde buscar, pero la conciencia me impide darte la solucion.

Ahi tienes toda la razon, se aprende de los errores y si quieres ser programador vas a necesitar equivocarte muchas veces.

IsaacMG
03/06/2012, 19:00
El caso es que he dicho desde un principio que no quiero que se me resuelva el ejercicio, está claro, y luego otra cosa es que lo estoy haciendo obligatoriamente, no quiero ser programador ni programar me hace mucha gracia, lo que pasa es que lo tengo que hacer sí o sí, y tengo el pequeño problema que el profesor a duras penas explica, y cuando lo hace no es demasiado bien que digamos...

Gracias de todas formas a todos por la ayuda, yo lo voy intentando y a ver si lo logro para mañana, que es cuando lo tengo que presentar.

Jurk
03/06/2012, 19:04
El caso es que he dicho desde un principio que no quiero que se me resuelva el ejercicio, está claro, y luego otra cosa es que lo estoy haciendo obligatoriamente, no quiero ser programador ni programar me hace mucha gracia, lo que pasa es que lo tengo que hacer sí o sí, y tengo el pequeño problema que el profesor a duras penas explica, y cuando lo hace no es demasiado bien que digamos...

Gracias de todas formas a todos por la ayuda, yo lo voy intentando y a ver si lo logro para mañana, que es cuando lo tengo que presentar.

mala combinacion, pero creo que el profe explica poco porque a programar se aprende con ensayo/error

IsaacMG
03/06/2012, 20:18
ok, de momento tengo esto que me puede servir:


/* memchr example */
#include <stdio.h>
#include <string.h>

int main ()
{
char * pch;
char str[] = "hello Example@string";
char frase[100];

pch = (char*) memchr (str, '@', strlen(str));

if (pch!=NULL){



while (*pch == '@') pch--;


printf ("%s", pch);
}


else
printf ("'@' not found.\n");
return 0;
}


Me imprime "e@string.com", hasta ahí genial.

Lo que pongo después del while es un "if (*pch == ' ') debería parar en el espacio y hacer el printf y imprimirme la dirección al completo, no? Pues no me imprime nada si uso el if. Luego he intentado poner un break después del if y me dice 'break statement not within loop or switch'... pero el while es un bucle no? D:

Vamos, lo que tengo que hacer es lo que hago, entonces hacer decrecer el puntero hasta que encuentre el espacio vacío, se pare y me imprima de ahí en adelante, que sería el mail...

Por qué no me imprime nada con el if o por qué no me deja usar el break?

no os ríais eh, que ya os he aclarado lo verde que voy en el tema...

gracias

ps: obviamente después de la dirección de correo si hubiera más texto lo imprimiría... *****, no sé cómo hacerlo xD

Jurk
03/06/2012, 20:36
tio, veo que te estas dejando los cuernos. Bien por ti, en serio.

Un consejo, no cambies los valores de los punteros... utilizalos como si fuesen un array

ejemplo:

int vector[]={10,20,30}

int *ptr;

ptr = vector;

printf ("%d", ptr[2]);



nos sacaria 30, pero el puntero ptr seguiria apuntado a 10

IsaacMG
03/06/2012, 22:08
NADA, me voy a pegar un tiro.

Solo quiero saber si hay alguna forma de con un while hacer que el puntero incremente automáticamente hasta encontrarse con un espacio en blanco, donde se parará.

No consigo hacer que incremente automáticamente de ninguna forma, solo hago que incremente una vez.

hardyx
04/06/2012, 01:12
Simplemente tienes que trocear las líneas con strtok() y sacar las palabras en un array (puede ser un array de punteros, o como quieras). Luego coges esas palabras y buscas las que tienen una arroba @ y un punto después. Y ahí tienes los correos.

Divide y vencerás amigo, no quieras hacerlo todo de un golpe.

---------- Post añadido a las 00:15 ---------- Post anterior a las 00:10 ----------



Solo quiero saber si hay alguna forma de con un while hacer que el puntero incremente automáticamente hasta encontrarse con un espacio en blanco, donde se parará.



char *p = linea; // esta es la línea
while (*p && *p != ' ') p++;
if(*p)
printf("Ahi tienes tu espacio: %s\n", p)


---------- Post añadido a las 01:12 ---------- Post anterior a las 00:15 ----------

Ejemplo de trocear una cadena con strtok. Puedes modificarlo para obtener los correos.

http://c.conclase.net/librerias/index.php?ansifun=strtok#inicio

IsaacMG
04/06/2012, 03:04
EDIT: LO HE CONSEGUIDO! (al 98%)


#include <stdio.h>
#include <string.h>

int main(argc, argv)
int argc;
char *argv[];
{

FILE * archivo;
char contenidoarchivo[100];
char *pch;
unsigned int i;
char *dominio[4] = {".net", ".com", ".es"};

fflush (stdin);
archivo = fopen(argv[1], "r");

while(feof(archivo)==0){
fgets(contenidoarchivo, 100, archivo);

pch = strtok (contenidoarchivo," ");
while (pch != NULL)
{
for(i = 0; i < 3; i++)
if(strstr(pch, dominio[i]) != NULL)
printf ("%s\n",pch);
pch = strtok (NULL, " ");
}
}
return(0);
}



Ya hace lo que quiero, pero por alguna razón a veces se me come algunas letras, por ejemplo, me presenta la lista:

"hola@ejemplo.com
hola1@ejemplo.net
hola2@ejemplo.es
la3@ejemplo.net
jemplo.com"

Pasa poco, pero pasa. Qué podría ser?
---------------------------------------------------------------------------------------------------------------------------
Bueno, me rindo. Voy a suspender el curso por un **** ejercicio de mierda que parecía fácil y es un **** infierno. Después de 4 días de intentar y intentar, no lo he conseguido.

Lo máximo que he hecho en el camino que me habéis indicado es coger mi fichero txt y trozearlo con el strtok, por lo que me presenta algo como
"hola
que
tal
ejemplo@ejemplo.com
yo
bien
ejemplo2@ejemplo.com
..."

Y ya no sé qué hacer para que sólo me presente todas las direcciones de correo del texto. El código es el siguiente:


#include <stdio.h>
#include <string.h>

int main(argc, argv)
int argc;
char *argv[];
{

FILE * archivo;
char contenidoarchivo[100];
char *pch;

fflush (stdin);
archivo = fopen(argv[1], "r");

while(feof(archivo)==0){
fgets(contenidoarchivo, 100, archivo);

pch = strtok (contenidoarchivo," ");
while (pch != NULL)
{

printf ("%s\n",pch);
pch = strtok (NULL, " ");
}
}
return(0);
}



He probado el strchr, he probado con el bucle que me ha pasado el compañero hardyx... he probado una cantidad bestial de cosas, y mi cabeza no logra resolverlo.

En fin, gracias a todos por la ayuda.

efegea
04/06/2012, 11:22
Si has conseguido trocearlo palabra por palabra, ahora sólo tienes que filtrar las que tienen arroba. Imprime en pantalla sólo si ha encontrado la arroba.

La primera parte que dices que te salen a trozos ya te lo expliqué por privado, sobre lo de que cogías de 100 en 100 caracteres y alguno podría estar entre medio ;)

javu61
04/06/2012, 16:39
Hola:

Si suspendes el curso es por que no sabes pensar como programador, no le eches la culpa al ejercicio que es muy sencillo realmente, no me ha costado mas de 2 minutos escribir el programa.

Lo primero que debemos hacer al programar es intentar pensar en como resolver el problema, no lanzarse a programar. Un problema habitual de principiante es buscar cosas complicadas, cuando hay estructuras sencillas que funcionan. Otro error es poner cosas de longitud fija, una cadena de 100 puede ser larga o corta, no lopuedes saber, por tanto no es una buena opción.

Prueba este programa a ver si te va mejor, no lo he compilado por que no tengo disponible un compilador, pero es una forma sencilla de hacerlo, simplemente sacas un solo caracter del fichero, si el caracter no es un separador de campos lo añades a un buffer, si es un separador analizas ese buffer. Cuando acaba el fichero tienes algo en el buffer, por lo que analizas lo que te queda.

Para analizar, recorres la cadena buscando un @, si lo encuentras es un mail. Esto debes ampliarlo, antes del @ debe haber un texto, no vale que empiece directamente por @. Detrás del @ debe haber un punto, y entre @ y punto un texto de longitud no cero. Tras el punto debe haber una extensión correcta.


#include <stdio.h>
#include <string.h>

#define CR 13
#define LF 10

int main(int argc, char *argv[]){

FILE * archivo; /* Este es el archivo que estamos leyendo */
char *buffer; /* La cadena que vamos montando con un solo token */
char *caracter; /* Un solo caracter del fichero que vamos leyendo */

fflush (stdin);
archivo = fopen(argv[1], "r");

while(feof(archivo)==0){
fgets(caracter, 1, archivo); /* Leemos un solo caracter del fichero */
if (caracter == " ") or (caracter == CR) or (caracter == LF) { /* Si es un separador */
explorar(buffer); /* Analizamos lo que llevamos de cadena buscando si existe un @ */
strcpy(buffer, ""); /* Limpiamos el buffer */
} else { /* Si no es un separador */
strcat(buffer, caracter); /* Añado el caracter a la cadena */
}
}
explorar(cadena); /* Procesamos lo que quede en el buffer */
return(0);
}

int explorar(char *cadena){
int i=0;
while (cadena[i] != \0d) { /* Recorremos toda la cadena */
if (cadena[i] == "@") { /* Si hay un @ la presentamos y salimos con true */
printf ("%s\n",cadena);
exit(0);
}
i++;
}
exit(1); /* Si no salimos por false */
}

IsaacMG
05/06/2012, 20:22
Muchas gracias javu61, me guardo tu código para estudiarmelo, ya no por nada, si no por aprender a nivel personal un poquito más de lo que sé (que es bien poco). De momento entregaré mi programa que es más sencillo y hace lo que le pido... además, lo saqué yo :p

Resulta que la fecha de entrega se ha extendido, pero me piden que haga una cosita más, y es que al final del programa el mismo me debe presentar el número de líneas que tengo en total. Lo he intentado de la siguiente forma:


#include <stdio.h>
#include <string.h>

int main(argc, argv)
int argc;
char *argv[];
{

FILE * archivo;
char contenidoarchivo[1000];
char *pch;
unsigned int i;
char *dominio[4] = {".net", ".com", ".es"};
int n;
int contador = 0;

fflush (stdin);
archivo = fopen(argv[1], "r");

while(feof(archivo)==0)
{
fgets(contenidoarchivo, 1000, archivo);

pch = strtok (contenidoarchivo," ;\n");
while (pch != NULL)
{
for(i = 0; i < 3; i++)
if(strstr(pch, dominio[i]) != NULL)
printf ("%s\n",pch);
pch = strtok (NULL, " ;\n");
}

for (n=0; n<strlen(contenidoarchivo); n++)
{
*contenidoarchivo=n;
if (contenidoarchivo[n]==10){
contador++;
}
}

}
printf("\nel numero de lineas es: %d", contador);
return(0);
}


Bucle que desde 0 vaya aumentando, y a cada cambio de línea (10) aumente el contador, y que luego me presente el contador... pero me sale siempre que el númeo de líneas es 0. Qué estoy haciendo tan rematadamente mal? :p

javu61
05/06/2012, 20:50
Hola:

fgets(contenidoarchivo, 1000, archivo) no lee 1000 caracteres del archivo de entrada, sino que lee una línea del fichero de entrada, hasta el caracter de CR o hasta que alcance la lóngitud máxima definida, por eso no encontrarás el CR en la cadena.

Debes cambiar



for (n=0; n<strlen(contenidoarchivo); n++)
{
*contenidoarchivo=n;
if (contenidoarchivo[n]==10){
contador++;
}
}


Por esto



contador++;



Por cierto, como hace mucho que no toco el C, en mi programa debes cambiar
fgets(caracter, 1, archivo); /* Leemos un solo caracter del fichero */

Por
caracter = fgetc(archivo); /* Leemos un solo caracter del fichero */
Saludos

IsaacMG
05/06/2012, 20:59
Entonces debe quedar así...


#include <stdio.h>
#include <string.h>

int main(argc, argv)
int argc;
char *argv[];
{

FILE * archivo;
char contenidoarchivo[1000];
char *pch;
unsigned int i;
char *dominio[4] = {".net", ".com", ".es"};
int n;
int contador = 0;

fflush (stdin);
archivo = fopen(argv[1], "r");

while(feof(archivo)==0)
{
fgets(contenidoarchivo, 1000, archivo);

pch = strtok (contenidoarchivo," ;\n");
while (pch != NULL)
{
for(i = 0; i < 3; i++)
if(strstr(pch, dominio[i]) != NULL)
printf ("%s\n",pch);
pch = strtok (NULL, " ;\n");
}
contador++;
}
printf("\nel numero de lineas es: %d", contador);
return(0);
}



Pero me dice que el número de líneas es 11... y son muchas más de 11.

Lo del fgets que me comentas... lo tenía en 100 en un principio, pero me presentaba las líneas cortadas, faltaban carácteres y por aquí ya me explicaron por qué era, así que lo puse a 1000 temporalmente hasta encontrar una solución mejor... al tenerlo en 1000 me presenta todo sin comerse ningun carácter.

Gracias!

Jurk
05/06/2012, 21:05
Muchas gracias javu61, me guardo tu código para estudiarmelo, ya no por nada, si no por aprender a nivel personal un poquito más de lo que sé (que es bien poco). De momento entregaré mi programa que es más sencillo y hace lo que le pido... además, lo saqué yo :p

Resulta que la fecha de entrega se ha extendido, pero me piden que haga una cosita más, y es que al final del programa el mismo me debe presentar el número de líneas que tengo en total. Lo he intentado de la siguiente forma:


#include <stdio.h>
#include <string.h>

int main(argc, argv)
int argc;
char *argv[];
{

FILE * archivo;
char contenidoarchivo[1000];
char *pch;
unsigned int i;
char *dominio[4] = {".net", ".com", ".es"};
int n;
int contador = 0;

fflush (stdin);
archivo = fopen(argv[1], "r");

while(feof(archivo)==0)
{
fgets(contenidoarchivo, 1000, archivo);

pch = strtok (contenidoarchivo," ;\n");
while (pch != NULL)
{
for(i = 0; i < 3; i++)
if(strstr(pch, dominio[i]) != NULL)
printf ("%s\n",pch);
pch = strtok (NULL, " ;\n");
}

for (n=0; n<strlen(contenidoarchivo); n++)
{
*contenidoarchivo=n;
if (contenidoarchivo[n]==10){
contador++;
}
}

}
printf("\nel numero de lineas es: %d", contador);
return(0);
}


Bucle que desde 0 vaya aumentando, y a cada cambio de línea (10) aumente el contador, y que luego me presente el contador... pero me sale siempre que el númeo de líneas es 0. Qué estoy haciendo tan rematadamente mal? :p

Por que no pruebas a utilizae una variable inicializada a cero que se incremente justo despues de esxribir el mail?

Al finalizar tendras el numero de mails

hardyx
05/06/2012, 21:07
Sólo comentar que la variable que llamas contenidoarchivo, no es el archivo completo, es sólo una línea cada vez hasta el retorno de carro. fgets() es eso lo que hace. Por lo tanto, si quieres contar las líneas sólo tienes que incrementar después de hacer fgets. No tienes que buscar el retorno (10), porque no lo vas a encontrar. fgets te lo quita.

Aquí te explica lo que hace:
http://c.conclase.net/librerias/?ansifun=fgets

Logann
05/06/2012, 22:39
Como te comentan tienes que entender lo que quires hacer.
1) Tienes que saber que és una mail : http://en.wikipedia.org/wiki/Email_address aqui explican que es y que simbolos puede contener y su longitud maxima
Intenta hacer una funcion que reciba un puntero a char y un tamaño y verifica si és un mail y si lo es lo imprime por pantalla.

2) Tienes que saber que caracteres pueden seprar un mail del resto de texto por exemplo: tabulador, espacio, intro...
Intenta leer el archivo poco a poco a poco, buscar caracteres separadores, para cada par de caracteres separadores tienes que llamar a la funcion de 1)

Intentalo hacer con fgets con el tamaño maximo de linea que esperas, si lo consigues, después mira como funciona fread...

swapd0
05/06/2012, 23:22
Un consejo, nunca escribas un bucle del estilo:

while (!feof(fichero))
{
...
}

El motivo es que la funcion feof() solo comprueba si el flag de fin de fichero esta activo, no comprueba que estemos al final del fichero. Debido a esto se puede dar el caso de que leas datos hasta el final del fichero (pero sin pasarte) y entres en el bucle while (entas una vez de mas) porque no se ha activado el flag y después intentes leer mas datos pero como estas al final no hay nada que leer, dependiendo de como tengas implementado el codigo la aplicación puede petar o añadir datos repetidos/basura en alguna lista que estés rellenando.

javu61
05/06/2012, 23:30
Te faltan las llaves de apertura y cierre del bucle for, por tanto el programa no hace lo que piensas. Por otro lado, si cuentas líneas leidas, pon el contador++ justo después del fgets, que está mas claro lo que hace.

Saludos

IsaacMG
07/06/2012, 20:52
Nada, no me sale :/

He puesto el contador inicializado a 0 justo después del fgets, pero claro, esto lo que hará será separarme las lineas del contenido del archivo original, las cuales no están separadas como yo quiero, de ahí que haya utilizado el strtok, que me las coloca tal que así:

"linea 1
linea 2
linea 3"

yo quiero que me cuente las lineas una vez ha acabado de hacer todo, es decir, después de pasar el strtok. He intentado poner el contador también justo al final, después del strtok,blabla, y me da números aleatorios y diferentes.

swapd0
07/06/2012, 21:03
si en vez del fgets usas un fscanf puede leer el fichero linea a linea, en vez de leer un buffer y buscar donde hay nuevas lineas

IsaacMG
07/06/2012, 22:23
Acabo de probar con fscanf, y he conseguido un que me lea todo igual excepto que se come muchisimos carácteres del inicio de cada línea y además donde deberían estar esos caracteres me imprime el printf que tengo abajo
"numero de lineas 1ejemplo@ejemplo.com
numero de lineas 2emplo@ejemplo.com
numero de lineas 3mplo@ejemplo.com" y así cada linea. Lo que también he visto que a partir de la línea X me sale esto seguido "número de linea41numero de linea42numero de linea 43" y así hasta 30 veces, y después continua imprimiendome las direcciones de correo...

alguna idea?

swapd0
07/06/2012, 22:55
o lees mal las lineas o las imprimes mal, usa el depurador y ejecuta el programa paso a paso para ver lo que lees y lo que imprimes.