Hola, he intentado siguiendo tus indicaciones solucionar el problema, he creado un contador, que recorre el fichero, y ahora lee todo ordenador, a mas con la funcion feof nueva ya no se va hasta el infinito. el problema ahora esta en la primera palabra que lee y la ultima.<div>
la primera palabra no la lee, va directo a la segunda, y la ultima palabra no la repite infinitamente, xo la repite 1 vez mas, es decir, la pone dos veces. no se como solucionarlo, ya que el contador con i=0 indica clarament que lea la primera palabra, y con la funcion feof, en teoria, no tendria k volver a entrar en el while, por tanto, no entiendo porque repite la ultima palabra antes de acabar.</div>
<div>muchas gracias por la ayuda, pego la nueva version a continuacion</div><div><br></div><div><div>#include <stdio.h></div><div>#include <string.h></div><div><br></div><div><br></div><div>struct t_palabra {                      // t_palabra es una estructura que contiene castellano ingles y contadores de aciertos y fallos</div>
<div>       char castellano[30];</div><div>       char ingles[30];</div><div>       int cont_aciertos;</div><div>       int cont_errores;</div><div>       };</div><div>       </div><div>              </div><div>int main (void)</div>
<div><br></div><div>{</div><div>    FILE *fichero;                       // apunta al fichero donde se guardaran las palabras y sus aciertos/fallos</div><div>    struct t_palabra palabra;            // definim la variable paraula.</div>
<div>    char respuesta[50];                  // l'usuari entra la seva resposta</div><div>    int i;                               // recorrer el ficher</div><div>    </div><div>struct t__virt_palabra {                    // l'utilitzo per augmentar els contadors cada cop k l'usuari practica 1 paraula. (nose una altre manera de fer-ho)</div>
<div>       char virt_castellano[30];</div><div>       char virt_ingles[30];</div><div>       int virt_cont_aciertos;</div><div>       int virt_cont_errores;</div><div>       };    </div><div>struct t__virt_palabra virt_palabra;        // definim la variable virt_palabra</div>
<div>    </div><div>    fichero = fopen ("datos.dat", "rb+");              // s'obre el ficher datos.dat. rb+ es correcte????? al ficher hi ha tant caracters</div><div>                                                       // castellano, ingles, com enters (els contadors) x tant te que ser binari, no?</div>
<div>    </div><div>    if (fichero == NULL)                                 // salta en cas que no existeixi l ficher datos.dat</div><div>       printf ("Error: No se ha podido abrir el fichero datos.dat.");</div>
<div>    </div><div>    else</div><div>    {   </div><div>        i=0;</div><div>        strcpy (respuesta, "hola");</div><div>        virt_palabra.virt_cont_aciertos = 0;</div><div>        virt_palabra.virt_cont_errores = 0;</div>
<div>        </div><div>        fseek(fichero, i*sizeof(struct t_palabra), SEEK_SET); // se pone el cursor al inicio de todo xk i=0</div><div>        </div><div>        while (!feof(fichero))                        // preguntar al usuari paraules, fins k sarrivi a la ultima paraula, </div>
<div>        {                                                     // despres d'aquesta tindria que parar!!!!! i no ho fa :s, tornar a preguntar </div><div>                                                              // sempre la ultima :(</div>
<div>            if(fread(&palabra, sizeof(palabra), 1, fichero)) {</div><div>                               </div><div>            fread(&palabra, sizeof(palabra), 1, fichero);     // en la primera iteracio, llegirm la primera paraula gracies a i=0</div>
<div>            printf ("\nEscribe la traduccion de...: ");       // preguntem la paraula</div><div>            printf ("\n%s: ", palabra.castellano);</div><div>            gets(respuesta);                                  // l'usuari entra la paraula</div>
<div>            </div><div>            // analitzar si l'usuari la encertat, o fallat, i incrementar els contadors corresponents x cada paraula</div><div>                            if (strcmp(respuesta, palabra.ingles) == 0)  // compara resposta amb palabra.ingles si es correcte...</div>
<div>                            {</div><div>                            printf ("\nCorrecto!");           // felicitem al usuari x cortesia, tenim que incrementar el contador d'encerts</div><div>                            </div>
<div>                                   // com que no es pot modificar nomes 1 apartat de la estructura paraula, tenim que introduir de nou tot...</div><div>                                   // copiem a la variable virtual (nomes serveix x traspar informacio) la paraula i la seva traduccio</div>
<div>                                   strcpy (virt_palabra.virt_castellano, palabra.castellano);</div><div>                                   strcpy (virt_palabra.virt_ingles, palabra.ingles);</div><div>                                   // incrementem el contador una unitat</div>
<div>                                   //palabra.cont_aciertos a la primera iteració val 0 (aixi sa inicialitzat)</div><div>                                   // i ho guardem a la virtual tb, x tal d copiar tot again.</div>
<div>                                   virt_palabra.virt_cont_aciertos = palabra.cont_aciertos + 1;</div><div>                                   </div><div>                                   // important: com que hem utilitzat fread, el curso esta darrera la paraula llegida ara!!</div>
<div>                                   // la variable virtual conte les noves dades, es a dir, amb el contador incrementat,</div><div>                                   // x tant, tenim que ficar el cursor al inici de la paraula k estavem treballant, xk </div>
<div>                                   // escrigui la informacio just a sobre de la paraula antiga</div><div>                                   // ara la i estava a la posicio dspres de size of (equivalent a i=0), es a dir, dspres de la primera paraula</div>
<div>                                   // en la primera iteració, ja que la i val 0, amb aquesta comanda tornem a la posicio inical</div><div>                                   </div><div>                                   fseek(fichero, i*sizeof(struct t_palabra), SEEK_SET);</div>
<div>                                   </div><div>                                   strcpy (palabra.castellano, virt_palabra.virt_castellano);</div><div>                                   strcpy (palabra.ingles, virt_palabra.virt_ingles);</div>
<div>                                   palabra.cont_aciertos = virt_palabra.virt_cont_aciertos;</div><div>                                   </div><div>                                   // i podem sobreescriure la paraula que voliem</div>
<div>                                   </div><div>                                   fwrite (&palabra, sizeof(palabra), 1, fichero);</div><div>                                   // important, el cursor torna a estar darrera de la primera paraula (en primera iteracio)</div>
<div>                                                                                         </div><div>                            }      // sino es correcte...</div><div>                            </div><div>                            </div>
<div>                            else</div><div>                                {</div><div>                                </div><div>                                printf ("\nIncorrecto.");</div><div>                                </div>
<div>                            </div><div>                                   virt_palabra.virt_cont_errores = palabra.cont_errores + 1; // mateixa estrategia</div><div>                                   strcpy (virt_palabra.virt_castellano, palabra.castellano);</div>
<div>                                   strcpy (virt_palabra.virt_ingles, palabra.ingles);</div><div>                                   </div><div>                                   fseek(fichero, i*sizeof(struct t_palabra), SEEK_SET);</div>
<div>                                   </div><div>                                   strcpy (palabra.castellano, virt_palabra.virt_castellano);</div><div>                                   strcpy (palabra.ingles, virt_palabra.virt_ingles);</div>
<div>                                   palabra.cont_errores = virt_palabra.virt_cont_errores;</div><div>                                  </div><div>                                   </div><div>                                    </div>
<div>                                   fwrite (&palabra, sizeof(palabra), 1, fichero);</div><div>                                   // important, ara el cursor esta despres de la paraula treballada</div><div>                                   </div>
<div>                                }</div><div>                                    </div><div>            // hem acabat la primera iteracio</div><div>            </div><div>            </div><div>            i++; // incrementem la i, per tal danar a la propera paraula.</div>
<div>            fseek(fichero, i*sizeof(struct t_palabra), SEEK_SET);   // coloquem el cursor a la seguent posicio, es a dir, a la posicio 1, </div><div>                                                                    // es a dir, a la segona paraula. nem cap a dalt, ja que al ficher</div>
<div>                                                                    // encara hi ha paraules, i tooorneeem a fer el while.</div><div>            }</div><div>            else {</div><div>                 printf ("\nfin!");</div>
<div>                 }</div><div>            }</div><div>              </div><div>              </div><div>        fclose (fichero);</div><div>        </div><div>        </div><div>        }</div><div>    </div><div> </div>
<div>fflush(stdin);</div><div>printf("\n\nPulse Intro para finalizar...");</div><div>getchar();</div><div><br></div><div><br></div><div>            </div><div>}</div><div><br></div><div><br></div><div><br></div>
<br><div class="gmail_quote">El 5 de marzo de 2012 10:35, Salvador Pozo <span dir="ltr"><<a href="mailto:salvador@conclase.net">salvador@conclase.net</a>></span> escribió:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
El pasado 2012-03-04 22:23:19, Albert_Munich escribió:<br>
<br>
A> Muchas gracias por la explicación,<br>
A> he corregido lo de SEEK_CUR, y ahora en teoria, lee la palabra, el cursor<br>
A> se queda despues de la palabra, y para sobreescribirla utilizo<br>
A> fseek(fichero, (-1)*sizeof(struct t_palabra), SEEK_CUR);<br>
A> y tampco me funciona, me repite todo el rato la segunda palabra, el mismo<br>
A> problema de siempre. no entiendo el porque, ya que despues del fwrite, el<br>
A> cursor queda detras d la palabra modificada, y con el siguiente fread<br>
A> dentro dl while, se tendria que leer la palabra que toca. no se como<br>
A> solucionarlo xk x logica lo haria asi, xo nose donde esta el error<br>
A> informatico, o si esta equivocada la logica aplicada.<br>
A> Me podrias ayudar? esque estoy aprendiendo a programar x mi cuenta y cuesta<br>
A> 1 poco.<br>
<br>
Hola:<br>
<br>
Bueno, mucho me temo que esta es una de esas "cosas raras" que pasan con la programación, cuando el lenguaje está limitado con respecto a las implementaciones reales de los sistemas operativos.<br>
<br>
Puede que me equivoque en el origen del problema (si es así, que alguien me corrija), pero me temo que este comportamiento de las funciones de ficheros está relacionada con el modo en que Windows implementa el sistema de archivos.<br>

<br>
En C++, usando streams, es posible que esto no pase, pero luego llegamos a esto.<br>
<br>
Los ficheros de acceso aleatorio pueden tener punteros de escritura y lectura diferentes, es decir, el punto en que se lee del fichero no tiene por qué ser el mismo en el que se escribe. Esto es evidente si el fichero se abre en modo "append", en los que podemos leer de cualquier punto, pero sólo se puede escribir al final. Pero lo cierto es que puede pasar en todos los tipos de ficheros.<br>

<br>
En tu programa fseek coloca los dos cursores del fichero, el de escritura y el de lectura, a a una posición anterior, pero al escribir los nuevos valores del registro sólo se actualiza el cursor de escritura, y el de lectura se mantiene en la misma posición. Por eso siempre leemos el segundo registro.<br>

<br>
Los streams de C++ disponen de funciones diferentes para colocar los cursores de lectura y escritura: seekg y seekp, y lo mismo para leer esas posiciones: tellg y tellp. Por lo que esto resulta más evidente.<br>
<br>
La solución es simple: colocar el cursor antes de realizar cada lectura. Para esto necesitarás un índice.<br>
<br>
Otro problema con tu programa es el uso de feof (creo que lo habías preguntado anteriormente).<br>
<br>
El bucle tiene esta forma:<br>
----8<------<br>
while(!feof(fichero)) {<br>
    fread(&palabra, sizeof(palabra), 1, fichero);<br>
    ...<br>
}<br>
----8<------<br>
<br>
Ahora imaginemos que hemos leído el último registro, y volvemos a repetir el bucle.<br>
Primero, la condición de fin de fichero es falsa, ya que es una bandera (un flag) que se almacena en la estructura FILE, y que sólo se actualiza después de una operación de lectura o escritura.<br>
Como feof es falsa, !feof es verdadera, y se ejecuta el bucle. Leemos una palabra, pero el cursor de lectura está al final del fichero, de modo que la lectura falla, y se activa la bandera de fin de fichero. Sin embargo, se procesa el registro.<br>

Cuando fread falla, el registro no se lee, de modo que palabra mantiene su valor actual. Esto hace, en un bucle normal (sin fseek), que el último registro se procese dos veces. En tu caso, el último registro se procesa hasta el infinito.<br>

<br>
En el caso de los ficheros hay que modificar este bucle:<br>
----8<------<br>
while(!feof(fichero)) {<br>
    if(fread(&palabra, sizeof(palabra), 1, fichero) {<br>
       ...<br>
    }<br>
}<br>
----8<------<br>
<br>
Es decir, sólo procesamos el registro leído si realmente lo hemos leído.<br>
<br>
Sobre este tema puede consultar la página de C con Clase sobre archivos:<br>
<a href="http://c.conclase.net/ficheros/index.php" target="_blank">http://c.conclase.net/ficheros/index.php</a><br>
<div class="HOEnZb"><div class="h5"><br>
Hasta pronto.<br>
<br>
--<br>
Salvador Pozo (Administrador)<br>
mailto:<a href="mailto:salvador@conclase.net">salvador@conclase.net</a><br>
_______________________________________________<br>
Lista de correo Cconclase <a href="mailto:Cconclase@listas.conclase.net">Cconclase@listas.conclase.net</a><br>
<a href="http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net" target="_blank">http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net</a><br>
Bajas: <a href="http://listas.conclase.net/index.php?gid=2&mnu=FAQ" target="_blank">http://listas.conclase.net/index.php?gid=2&mnu=FAQ</a><br>
</div></div></blockquote></div><br></div>