C/Exercicios:Traballar con ficheiros/Solucións

En Galilibros, o Wikibooks en galego.

Solución 1[editar]

#include <stdio.h>

int main(int argc, char * argv[])
{
  // Declaración de variables
  FILE * entrada;
  char cadea[128];
  int peche;
  
  
    // Comprobación do número de argumentos na chamada
    if(argc != 2)
    {
      printf("O programa debe executarse cun único argumento,\n");
      printf("que debe conter a ruta ao ficheiro de texto a ler.\n");
      return -1;
    }
  
  // Apertura do ficheiro coas palabras
  entrada = fopen(argv[1], "r");
  
    // Se non se dá aberto o ficheiro:
    if(entrada == NULL)
    {
      printf("Non se puido ler o ficheiro de entrada: «%s».\n",argv[1]);
      return -1;
    }
  
  // Proceso de lectura e impresión en pantalla das cadeas do ficheiro
  fgets(cadea, sizeof(cadea), entrada);
  while(!feof(entrada) && !ferror(entrada))
  {
    printf("%s",cadea);
    fgets(cadea, sizeof(cadea), entrada);
  }
  
  // Peche do ficheiro
  peche = fclose(entrada);
  if(peche == EOF)
  {
    printf("O ficheiro de entrada, «%s», non de puido pechar correctamente,\n",argv[1]);
    printf("por tanto pecharase automaticamente ao rematar a execución do programa.\n");
  }
  
  // Saída correcta do programa
  return 0;
}

Solución 2[editar]

#include <stdio.h>

int main(int argc, char * argv[])
{
  // Declaración de variables
  FILE * entrada;
  FILE * saida;
  char cadea[128];
  int peche;
  
  
    // Comprobación do número de argumentos na chamada
    if(argc != 3)
    {
      printf("O programa debe executarse con dous argumentos:\n");
      printf("1. a ruta do ficheiro de entrada e\n");
      printf("1. a ruta do ficheiro de saída.\n");
      return -1;
    }
  
  // Apertura do ficheiro coas palabras
  entrada = fopen(argv[1], "r");
  saida = fopen(argv[2], "w");
  
    // Se non se dá aberto algún ficheiro:
    if(entrada == NULL)
    {
      printf("Non se puido ler o ficheiro de entrada: «%s».\n",argv[1]);
      return -1;
    }
    if(saida == NULL)
    {
      printf("Non se puido ler o ficheiro de saída: «%s».\n",argv[2]);
      return -1;
    }
  
  // Proceso de lectura e gravado das cadeas do ficheiro de entrada no de saída
  fgets(cadea, sizeof(cadea), entrada);
  
  while(!feof(entrada) && !ferror(entrada))
  {
    fputs("→ ",saida);
    fputs(cadea, saida);
    fgets(cadea, sizeof(cadea), entrada);
  }
  
  // Peche do ficheiro
  peche = fclose(entrada);
  if(peche == EOF)
  {
    printf("O ficheiro de entrada, «%s», non de puido pechar correctamente,\n",argv[1]);
    printf("por tanto pecharase automaticamente ao rematar a execución do programa.\n");
  }
  peche = fclose(saida);
  if(peche == EOF)
  {
    printf("O ficheiro de saída, «%s», non de puido pechar correctamente,\n",argv[2]);
    printf("por tanto pecharase automaticamente ao rematar a execución do programa.\n");
  }
  
  // Saída correcta do programa
  return 0;
}

Solución 3[editar]

#include <stdio.h>

int main(int argc, char * argv[])
{
  // Declaración de variables
  FILE * entrada;
  FILE * saida;
  char cadea[128];
  int control;
  int inicial;
  
  
    // Comprobación do número de argumentos na chamada
    if(argc != 3)
    {
      printf("O programa debe executarse con dous argumentos:\n");
      printf("1. a ruta do ficheiro de entrada e\n");
      printf("1. a ruta do ficheiro de saída.\n");
      return -1;
    }
  
  // Apertura do ficheiro coas palabras
  entrada = fopen(argv[1], "r");
  saida = fopen(argv[2], "w");
  
    // Se non se dá aberto algún ficheiro:
    if(entrada == NULL)
    {
      printf("Non se puido ler o ficheiro de entrada: «%s».\n",argv[1]);
      return -1;
    }
    if(saida == NULL)
    {
      printf("Non se puido ler o ficheiro de saída: «%s».\n",argv[2]);
      return -1;
    }
  
  // Proceso
  inicial = fgetc(entrada);
  
  while(!feof(entrada) && !ferror(entrada))
  {
    control = fputc(inicial,saida);
    if(control == EOF)
      break;
    control = fputc(' ',saida);
    if(control == EOF)
      break;
    fgets(cadea, sizeof(cadea), entrada);
    if(feof(entrada) || ferror(entrada))
      break;
    inicial = fgetc(entrada);
  }
  
  // Peche do ficheiro
  control = fclose(entrada);
  if(control == EOF)
  {
    printf("O ficheiro de entrada, «%s», non de puido pechar correctamente,\n",argv[1]);
    printf("por tanto pecharase automaticamente ao rematar a execución do programa.\n");
  }
  control = fclose(saida);
  if(control == EOF)
  {
    printf("O ficheiro de saída, «%s», non de puido pechar correctamente,\n",argv[2]);
    printf("por tanto pecharase automaticamente ao rematar a execución do programa.\n");
  }
  
  // Saída correcta do programa
  return 0;
}

Solución 4[editar]

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

struct ficha
{
  char nome[63];
  char alcume[31];
  unsigned short int idade;
  unsigned short int camiseta;
  float media;
};

void limpeza(void); // Función para limpar o salto de liña que deixa a función scanf()

int main(int argc, char * argv[])
{
  // Declaración de variables
  FILE * ficheiro;
  struct ficha xogadores[5];
  struct ficha temporal;
  unsigned short int contador;
  int control1;
  char * control2;
  char resposta;
  
    // Comprobación do número de argumentos na chamada
    if(argc != 2)
    {
      printf("O programa debe executarse cun argumento que indique a ruta\n");
      printf("do ficheiro onde se van gardar os datos do 5 inicial.\n");
      return -1;
    }
    
  // Proceso de introdución de datos:
  printf("Introduza os datos do 5 inicial:\n");
  for(contador = 0;contador < 5;contador++)
  {
    printf("  Xogador %d\n",contador+1);
    
      do
      {
	printf(" Nome e apelidos: ");
	control2 = fgets(xogadores[contador].nome,sizeof(xogadores[contador].nome),stdin);
      }
      while(control2 == NULL || !strlen(xogadores[contador].nome));
    
      do
      {
	printf(" Alcume (se ten): ");
	control2 = fgets(xogadores[contador].alcume,sizeof(xogadores[contador].alcume),stdin);
      }
      while(control2 == NULL);
      
      do
      {
	printf(" Idade: ");
	control1 = scanf("%hu",&xogadores[contador].idade);limpeza();
      }
      while(control1 != 1);
      
      do
      {
	printf(" Camiseta: ");
	control1 = scanf("%hu",&xogadores[contador].camiseta);limpeza();
      }
      while(control1 != 1);
      
      do
      {
	printf(" Media de goles por encontro: ");
	control1 = scanf("%f",&xogadores[contador].media);limpeza();
      }
      while(control1 != 1);
      
  }
  
  // Apertura do ficheiro para gravar nel, e tamén para ler.
  ficheiro = fopen(argv[1], "w+b");
  
    // Se non se dá aberto o ficheiro
    if(ficheiro == NULL)
    {
      printf("Non se puido ler o ficheiro: «%s».\n",argv[1]);
      return -1;
    }
  
  printf("Gravando os datos en disco...\n");
  control1 = fwrite(xogadores, sizeof(xogadores[0]), 5, ficheiro);
  if(control1 != 5)
  {
    printf("Houbo un erro ao gravar os datos en disco.\n");
    printf("Pasoulle algo ao ficheiro «%s»?.\n",argv[1]);
  }
  else
    printf("                             ...feito.\n");
  
  printf("Quere revisar os datos introducidos (S/n)? ");
  resposta = getchar();
    
    if(resposta == 'n')
      return 0; // Saída correcta do programa
  
  // Toca ler o ficheiro dende o principio, así que
  
    // poñemos o punteiro de lectura e escritura ao principio do ficheiro
    rewind(ficheiro);
    
    // e lemos:
    for(contador = 0;contador < 5;contador++)
    {
      printf("  Xogador %d\n",contador+1);
            
	control1 = fread(&temporal, sizeof(temporal), 1, ficheiro);
	if(control1 != 1)
	{
	 printf("Houbo un problema ao ler o ficheiro de datos: «%s».",argv[1]);
	 return -1;
	}
	
      printf("    Nome completo: %s",temporal.nome);
      printf("    Alcume: %s",temporal.alcume);
      printf("    Idade: %hu\n",temporal.idade);
      printf("    Camiseta: %hu\n",temporal.camiseta);
      printf("    Media de goles por encontro: %f\n",temporal.media);
    }
    
  // Peche do ficheiro
  control1 = fclose(ficheiro);
  if(control1 == EOF)
  {
    printf("O ficheiro «%s» non de puido pechar correctamente, por tanto\n",argv[1]);
    printf("pecharase automaticamente ao rematar a execución do programa.\n");
  }
  
  // Saída correcta do programa
  return 0;
}

void limpeza(void) 
{ 
  // Declaración de variables
  int ch; 
 
  // Limpar
  while
  (
    (ch = fgetc(stdin)) != EOF
    &&
    ch != '\n'
  );
}

Solución 5[editar]

// Ficheiros de cabeceira.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Definicións de valores.
#define CARACTERESMAXIMOS 50

// Declaración de estruturas.

  // Estrutura para a matriz dinámica de nomes.
  typedef struct
  {
    unsigned short int cantidade;
    char ** elementos;
  } lista;
  
  // Estrutura para as fichas con nome e idade.
  typedef struct
  {
    char nome[CARACTERESMAXIMOS];
    unsigned short int idade;
  } ficha;
  
// Declaracións de funcións.
lista funcion1(FILE * ficheiro);
signed short int funcion2(char * cadea, lista nomes);
void funcion3(lista nomes, char * rutadoficheiro);
void limpeza(void); // Función para limpar o lixo da función scanf()

lista funcion1(FILE * ficheiro)
{
  // Declaración de variables.
  lista nomes = {0, NULL};
    // É importante que o punteiro teña valor nulo para o realloc().
    // Ademais, sendo nomes.cantidade 0, se non hai nomes non fai falla establecer este valor de novo.
  char cadea[CARACTERESMAXIMOS];
  
  // Por se o punteiro de lectura e escritura do ficheiro non está ao principio:
  rewind(ficheiro);

  // Comeza o verdadeiro proceso
  fgets(cadea,sizeof(cadea),ficheiro); // Lectura dunha liña do ficheiro.
  
  while(!feof(ficheiro) && !ferror(ficheiro))
  {
    if(funcion2(cadea,nomes) == -1) // Se a cadea non existe aínda na lista.
    {
      nomes.cantidade++; // A lista de nomes vai ter un novo elemento.
      nomes.elementos = (char **) realloc(nomes.elementos,sizeof(char *)*nomes.cantidade); // Amplíase o espazo na lista.
      nomes.elementos[nomes.cantidade-1] = (char *) malloc(sizeof(char)*strlen(cadea)); // Faise espazo para o novo nome.
      strcpy(nomes.elementos[nomes.cantidade-1],cadea); // Introdúcese o novo nome na lista.
    }
    
    fgets(cadea,sizeof(cadea),ficheiro); // Lectura dunha liña do ficheiro.
  }

  return nomes;
}

signed short int funcion2(char * cadea, lista nomes)
{
  // Declaración de variables.
  signed short int indice;

  // Proceso de busca dunha cadea igual.
  for(indice = 0;indice < nomes.cantidade;indice++)
  {
    if(!strcmp(nomes.elementos[indice], cadea)) // Se son iguais...
      return indice; // ...devolve o lugar onde se atopa a primeira cadea igual.
  }

  // Se non se atopou unha cadea igual:
  return -1;
}

void funcion3(lista nomes, char * rutadoficheiro)
{
  // Declaración de variables.
  int indice;
  FILE * ficheiro;
  ficha * datos;
  int control1;
  int lonxitude;
  
  // En caso de que non haxa nomes na lista, a función devolve 
  if(nomes.cantidade == 0)
  {
    printf("A lista de nomes está baleira.\n");
    return;
  }
  
  // Se a lista non está baleira, o primeiro é facer espazo para os datos.
  datos = (ficha *) malloc(sizeof(ficha)*nomes.cantidade);

  // Créase o ficheiro que vai conter os datos.
  ficheiro = fopen(rutadoficheiro, "wb"); // Ábrese en forma binaria.

  // Proceso de obtención da idade correspondente a cada nome.
  for(indice = 0;indice < nomes.cantidade;indice++)
  {
    strcpy(datos[indice].nome, nomes.elementos[indice]);
    printf("Nome: %s",datos[indice].nome); // O salto de liña vai incluído no nome.
    do
    {
      printf("Idade: ");
      control1 = scanf("%d",&datos[indice].idade); limpeza();
    }
    while(control1 != 1 || datos[indice].idade < 0);
  }

  // Escritura dos datos no ficheiro.
  fwrite(datos,sizeof(ficha),nomes.cantidade,ficheiro);

  // Peche do ficheiro.
  control1 = fclose(ficheiro);
  if(control1 == EOF)
  {
    printf("Houbo un erro ao pechar o ficheiro «%s».\n",rutadoficheiro);
    printf("O ficheiro pecharase automaticamente ao rematar a execución do programa.\n");
  }
}

void limpeza(void)
{
  char ch;
  while( (ch = fgetc(stdin)) != EOF && ch != '\n' );
}

// FUNCIÓN PRINCIPAL
// Non forma parte do exercicio, pero permite poñer a proba as funcións do mesmo.
int main(void)
{
  // Declaración de variables.
  lista datos;
  ficha temporal;
  FILE * ficheiro;
  int indice;
  int control;

  // Posta a proba de funcion1() e funcion2().
  printf("Posta a proba de funcion1() e funcion2():\n");

    ficheiro = fopen("datos.txt","r"); // Previamente haberá que crear o ficheiro coa lista de nomes.
    
    datos = funcion1(ficheiro);

    printf("Datos gardados:\n");
    for(indice = 0; indice < datos.cantidade; indice++)
    {
      printf("%s",datos.elementos[indice]);
    }
    printf("\n");

    fclose(ficheiro);

  // Posta a proba da funcion3().
  printf("Posta a proba de funcion3():\n");
  
    // Execución da función.
    funcion3(datos, "datos.dat");
    
    // Lectura dos datos gardados.
    ficheiro = fopen("datos.dat", "rb");
    printf("  Léronse os seguintes datos:\n");
    for(indice = 0; indice < datos.cantidade; indice++)
    {
      control = fread(&temporal, sizeof(ficha), 1, ficheiro);
	if(control != 1)
	{
	 printf("Houbo un problema ao ler o ficheiro de datos: «%s».\n","datos.dat");
	 return -1; // Saída do programa.
	}
      printf("  → %s    %hu anos\n",temporal.nome, temporal.idade); // Tendo en conta que o nome ten un salto de liña.
    }
    fclose(ficheiro);    
    
  // Liberación da memoria dinámica reservada.
  for(indice = 0; indice < datos.cantidade; indice++)
  {
    free(datos.elementos[indice]);
  }
  free(datos.elementos);

  // Saída correcta do programa.
  return 0;
}

Solución 6[editar]

// Ficheiros de cabeceira:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Definición de constantes:
#define LONXITUDERUTA 128
#define LONXITUDENOME 66
#define LONXITUDECODIGO 6
#define CANTIDADENOTAS 3

// Definicións de tipos:
typedef struct
{
  char codigo[LONXITUDECODIGO+1];
  char nome[LONXITUDENOME];
  unsigned short int idade;
  float notas[CANTIDADENOTAS];
  float notafinal;
  signed short int marca;
} estrutura;

// Prototipos das funcións:
void LimparOBuferDeEntrada(void);
unsigned short int Menu(void);
void Engadir(FILE * ficheiro, signed long int rexistro);
void Borrar(FILE * ficheiro, signed long int rexistro);
void Consultar(FILE * ficheiro, signed long int rexistro);

int main(int argc, char * argv[])
{
  // Declaración de variables:
  FILE * ficheiro;
  char rutadoficheiro[LONXITUDERUTA];
  unsigned short int lonxitudedacadea;
  char resposta;
  signed int comprobacion;
  unsigned short int escolla; // Escolla do menú.
  signed long int rexistro; // Número do rexistro co que se vai traballar.

  // Análise dos argumentos introducidos:
  if(argc == 2)
  {
    // Gárdase a ruta fornecida como primeiro argumento:
    strcpy(rutadoficheiro, argv[1]);
  }
  else
  {
    if(argc > 2) // Se usuario introduciu argumentos de máis...
    {
      printf("Introduciu máis argumentos dos que require a execución do programa.\n");
      printf("Que quere facer?\n");
      printf("  1. Continuar a execución do programa (por defecto) ou\n");
      printf("  2. saír?\n");
      resposta = getchar();
      if(resposta != '\n') // Se se introduciu algún carácter antes te premer INTRO:
	LimparOBuferDeEntrada();
      if(resposta == '2') // Se o usuario decidiu saír...
	return 0;
    }

    do
    {
      // Pídese o nome do ficheiro:
      printf("Introduza o nome do ficheiro do que quere ler os datos:\n");
      fgets(rutadoficheiro, LONXITUDERUTA, stdin);

      lonxitudedacadea = strlen(rutadoficheiro);
    }
    while(lonxitudedacadea == 1);
    rutadoficheiro[lonxitudedacadea-1] = '\0'; // Bórrase o salto de liña.
  }
  
  // Ábrese o ficheiro que se atopa na ruta indicada polo usuario:
  ficheiro = fopen(rutadoficheiro, "r+");

  if(ficheiro == NULL) // Se non se deu aberto o ficheiro...
  {
    printf("O ficheiro «%s» non existe, quere crealo (S/n)? ",rutadoficheiro);
    resposta = getchar();
    if(resposta != '\n') // Se se introduciu algún carácter antes te premer INTRO:
      LimparOBuferDeEntrada();
    if(resposta == 'n') // Se o usuario decidiu saír...
      return 0;
    else // Se o usuario decidiu crear o ficheiro...
    {
      // Ábrese en modo de «lectura e escritura forzando a súa creación»:
      ficheiro = fopen(rutadoficheiro, "w+");
    }
  }
  
  while(-1)
  {
    // Chamada ao menú:
    escolla = Menu();
    
    switch(escolla)
    {
      case 1:
	// Pedir o número do rexistro:
	do
	{
	 printf("Introduza a posición do rexistro que quere engadir: ");
	 comprobacion = scanf("%ld",&rexistro); LimparOBuferDeEntrada();
	}
	while(comprobacion != 1 || rexistro < 1);
	Engadir(ficheiro, rexistro);
	break;
	
      case 2:
	// Pedir o número do rexistro:
	do
	{
	 printf("Introduza a posición do rexistro que quere borrar: ");
	 comprobacion = scanf("%ld",&rexistro); LimparOBuferDeEntrada();
	}
	while(comprobacion != 1 || rexistro < 1);
	Borrar(ficheiro, rexistro);
	break;
	
      case 3:
	// Pedir o número do rexistro:
	do
	{
	 printf("Introduza a posición do rexistro que quere consultar: ");
	 comprobacion = scanf("%ld",&rexistro); LimparOBuferDeEntrada();
	}
	while(comprobacion != 1 || rexistro < 1);
	Consultar(ficheiro, rexistro);
	break;
	
      case 4:
      default:
	// Peche do ficheiro:
	comprobacion = fclose(ficheiro);
	if(comprobacion == EOF)
	 printf("Houbo un erro ao pechar o ficheiro «%s»,\npecharase automaticamente ao rematar a execución do programa.\n",rutadoficheiro);
  
	// Saída correcta do programa.
	return 0;
    }
  }
}

void LimparOBuferDeEntrada(void)
{
  // Declaración de variables:
  int caracter;
  
  // Proceso de limpeza:
  while ( (caracter = fgetc(stdin)) != EOF && caracter != '\n' );
}

unsigned short int Menu(void)
{
  // Declaración de variables:
  signed int comprobacion;
  unsigned short int escolla;
  
  printf("\n");
  printf("Que quere facer?\n");
  printf("  1. Engadir un rexistro.\n");
  printf("  2. Eliminar un rexistro.\n");
  printf("  3. Consultar un rexistro en pantalla.\n");
  printf("  4. Saír (por defecto).\n");
  printf("Opción: ");
  comprobacion = scanf("%hu",&escolla); LimparOBuferDeEntrada();
  if(escolla >= 1 && escolla <= 4 || comprobacion == 1)
    return escolla;
  else
    return 4;
}

void Engadir(FILE * ficheiro, signed long int rexistro)
{
  // Declaración de variables.
  signed int comprobacion;
  estrutura * temporal;
  signed long int tamano;
  signed long int diferencia;
  unsigned short int indice;
  char resposta;
  unsigned short int lonxitudedacadea;
  
  // Comprobar se existe o ficheiro:
  if(ficheiro == NULL)
  {
    printf("Non se puido dar de alta un rexistro: o ficheiro dos rexistros non está aberto.\n");
    return;
  }

  // Calcular o tamaño actual do ficheiro:
  comprobacion = fseek(ficheiro, 0L, SEEK_END);
  if(comprobacion)
  {
    printf("Non se puido dar de alta un rexistro: houbo un erro ao ler o ficheiro.\n");
    return;
  }
  tamano = ftell(ficheiro)/(long)sizeof(*temporal);
  
  // Asignarlle tamaño á estrutura “temporal”:
  temporal = (estrutura *) malloc(sizeof(*temporal));
  
  if(rexistro > tamano)// Se non hai espazo para o rexistro...
  {
    // Comprobar canto espazo adicional fai falla:
    diferencia = rexistro - tamano;
    
    // Marcar como lixo os novos rexistros que se van engadir:
    temporal[0].marca = 0;
      
    // Ampliar o ficheiro ata poñer o punteiro ao principio do novo rexistro (espazo adicional necesario -1).
    fwrite(temporal, sizeof(*temporal), diferencia-1, ficheiro);
  }
  else
  {
    // Situar o punteiro de lectura e escritura ao principio do rexistro:
    comprobacion = fseek(ficheiro,(rexistro - 1L)*(long)sizeof(*temporal), SEEK_SET);
    if(comprobacion)
    {
      printf("Non se puido dar de alta un rexistro: houbo un erro ao ler o ficheiro.\n");
      // Libérase a memoria dinámica reservada:
      free(temporal);
      return;
    }

    // Intentar ler o rexistro:
    fread(temporal, sizeof(*temporal), 1, ficheiro);
    
    if(temporal[0].marca != 0) // Se a marca do rexistro sinala que é un rexistro activo...
    {
      // ...preguntar ao usuario se quere substituír os datos actuais ou volver ao menú.
      printf("Aparentemente, o rexistro xa contén os datos dun alumno:\n");
	
	// Datos do alumno actual:
	printf(" | Codigo: %s.\n", &temporal[0].codigo[0]);
	printf(" | Nome: %s.\n", &temporal[0].nome[0]);
	printf(" | Idade: %hu.\n", temporal[0].idade);
	printf(" | Notas: %.2f, %.2f e %.2f.\n", temporal[0].notas[0], temporal[0].notas[1], temporal[0].notas[2]);
	printf(" | Nota final: %.0f.\n",temporal[0].notafinal);
      
      printf("Que quere facer?\n");
      printf("  1. Substituír os datos actuais con novos datos (por defecto) ou\n");
      printf("  2. volver ao menú?\n");
      resposta = getchar();
      if(resposta != '\n') // Se se introduciu algún carácter antes te premer INTRO:
	LimparOBuferDeEntrada();
      if(resposta == '2') // Se o usuario decidiu volver ao menú...
      {    
	// Libérase a memoria dinámica reservada:
	free(temporal);
    
	return;
      }
    }
  }

  // Pídense os datos do novo alumno:
  printf("Datos do alumno:\n");
  
    // Código.
    printf("  Código: ");
    fgets(temporal[0].codigo, LONXITUDECODIGO+1, stdin);
    lonxitudedacadea = strlen(temporal[0].codigo);
    
    while(temporal[0].codigo[LONXITUDECODIGO-1] == '\n' || lonxitudedacadea < LONXITUDECODIGO)
    {
      printf("  → O código introducido é curto de máis. Introduza un código correcto.\n");
      printf("  Código: ");
      fgets(temporal[0].codigo, LONXITUDECODIGO+1, stdin);
      lonxitudedacadea = strlen(temporal[0].codigo);
    }
    
    LimparOBuferDeEntrada();
    
    // Nome.
    printf("  Nome: ");
    fgets(temporal[0].nome, LONXITUDENOME, stdin);
    lonxitudedacadea = strlen(temporal[0].nome);
    temporal[0].nome[lonxitudedacadea-1] = '\0';
    
    // Idade.
    do
    {
      printf("  Idade: ");
      comprobacion = scanf("%hu",&temporal[0].idade); LimparOBuferDeEntrada();
    }
    while(comprobacion != 1);
    
    // Notas.
    for(indice = 0; indice < CANTIDADENOTAS; indice++)
    {
      do
      {
	printf(" Nota %d: ", indice+1);
	comprobacion = scanf("%f",&temporal[0].notas[indice]); LimparOBuferDeEntrada();
      }
      while(comprobacion != 1);
    }
    
    // Calcúlase a nota final.
    temporal[0].notafinal = (temporal[0].notas[0] + temporal[0].notas[1] + temporal[0].notas[2]) / CANTIDADENOTAS;
    
    // Márcase o rexistro coma existente (-1).
    temporal[0].marca = (unsigned short int)-1;
    
  // Ponse o punteiro de lectura e escritura ao principio do rexistro:
  comprobacion = fseek(ficheiro,(rexistro - 1L)*(long)sizeof(*temporal), SEEK_SET);
  if(comprobacion)
  {
    printf("Non se puido continuar dando de alta un novo rexistro: houbo un erro ao ler o ficheiro.\n");
    // Libérase a memoria dinámica reservada:
    free(temporal);
    return;
  }

  // Grávanse nese rexistro.
  fwrite(temporal, sizeof(*temporal), 1, ficheiro);
  
  // Libérase a memoria dinámica reservada:
  free(temporal);
  
  // Saída correcta da función:
  return;
}

void Borrar(FILE * ficheiro, signed long int rexistro)
{
  // Declaración de variables.
  signed int comprobacion;
  estrutura * temporal;
  signed long int tamano;
  signed long int diferencia;
  char resposta;
  
  // Comprobar se existe o ficheiro:
  if(ficheiro == NULL)
  {
    printf("Non se puido borrar o rexistro: o ficheiro dos rexistros non está aberto.\n");
    return;
  }

  // Calcular o tamaño actual do ficheiro:
  comprobacion = fseek(ficheiro, 0L, SEEK_END);
  if(comprobacion)
  {
    printf("Non se puido borrar o rexistro: houbo un erro ao ler o ficheiro.\n");
    return;
  }
  tamano = ftell(ficheiro)/(long)sizeof(*temporal);
  
  if(rexistro > tamano)
  {
    printf("Non se puido borrar o rexistro: non hai tal rexistro.\n");
    return;
  }
  // Situar o punteiro de lectura e escritura ao principio do rexistro:
  comprobacion = fseek(ficheiro,(rexistro - 1L)*(long)sizeof(*temporal), SEEK_SET);
  if(comprobacion)
  {
    printf("Non se puido borrar o rexistro: houbo un erro ao ler o ficheiro.\n");
    return;
  }
  
  // Asignarlle tamaño á estrutura “temporal”:
  temporal = (estrutura *) malloc(sizeof(*temporal));

  // Intentar ler o rexistro:
  fread(temporal, sizeof(*temporal), 1, ficheiro);
  
  if(temporal[0].marca == 0) // Se a marca do rexistro sinala que é lixo...
  {
    printf("Non se puido borrar o rexistro: xa fora borrado, ou creárase baleiro.\n");
    // Libérase a memoria dinámica reservada:
    free(temporal);
    return;
  }
  
  // Visualización dos datos actuais:
  printf("  | Codigo: %s.\n", &temporal[0].codigo[0]);
  printf("  | Nome: %s.\n", &temporal[0].nome[0]);
  printf("  | Idade: %hu.\n", temporal[0].idade);
  printf("  | Notas: %.2f, %.2f e %.2f.\n", temporal[0].notas[0], temporal[0].notas[1], temporal[0].notas[2]);
  printf("  | Nota final: %.0f.\n",temporal[0].notafinal);
  
  // Petición de confirmación antes de borrar o ficheiro:
  printf("Está seguro de que quere borrar o rexistro?\n");
  printf("  1. Si (por defecto).\n");
  printf("  2. Non (volver ao menú).\n");
  resposta = getchar();
  if(resposta != '\n') // Se se introduciu algún carácter antes te premer INTRO:
    LimparOBuferDeEntrada();
  if(resposta == '2') // Se o usuario decidiu volver ao menú...
  {    
    // Libérase a memoria dinámica reservada:
    free(temporal);
    return;
  }
  
  temporal[0].marca = 0; // Márcase como lixo o rexistro temporal.
  
  // Ponse o punteiro de lectura e escritura ao principio do rexistro:
  comprobacion = fseek(ficheiro,(rexistro - 1L)*(long)sizeof(*temporal), SEEK_SET); 
  if(comprobacion)
  {
    printf("Non se puido continuar borrando o rexistro: houbo un erro ao ler o ficheiro.\n");
    // Libérase a memoria dinámica reservada:
    free(temporal);    
    return;
  }

  // Grávanse o rexistro marcado.
  fwrite(temporal, sizeof(*temporal), 1, ficheiro);
  
  // Libérase a memoria dinámica reservada:
  free(temporal);
  
  // Saída correcta da función:
  return;
}

void Consultar(FILE * ficheiro, signed long int rexistro)
{
  // Declaración de variables.
  signed int comprobacion;
  estrutura * temporal;
  signed long int tamano;
  signed long int diferencia;
  
  // Comprobar se existe o ficheiro:
  if(ficheiro == NULL)
  {
    printf("Non se puido consultar o rexistro: o ficheiro dos rexistros non está aberto.\n");
    return;
  }

  // Calcular o tamaño actual do ficheiro:
  comprobacion = fseek(ficheiro, 0L, SEEK_END);
  if(comprobacion)
  {
    printf("Non se puido consultar o rexistro: houbo un erro ao ler o ficheiro.\n");
    return;
  }
  tamano = ftell(ficheiro)/(long)sizeof(*temporal);
  
  if(rexistro > tamano)
  {
    printf("Non se puido consultar o rexistro: non hai tal rexistro.\n");
    return;
  }
  // Situar o punteiro de lectura e escritura ao principio do rexistro:
  comprobacion = fseek(ficheiro,(rexistro - 1L)*(long)sizeof(*temporal), SEEK_SET);
  if(comprobacion)
  {
    printf("Non se puido consultar o rexistro: houbo un erro ao ler o ficheiro.\n");
    return;
  }
  
  // Asignarlle tamaño á estrutura “temporal”:
  temporal = (estrutura *) malloc(sizeof(*temporal));

  // Intentar ler o rexistro:
  fread(temporal, sizeof(*temporal), 1, ficheiro);
  
  if(temporal[0].marca == 0) // Se a marca do rexistro sinala que é lixo...
  {
    printf("Non se puido ler o rexistro: xa fora borrado, ou creárase baleiro.\n");
    // Libérase a memoria dinámica reservada:
    free(temporal);
    return;
  }
  
  // Visualización dos datos actuais:
  printf("  | Codigo: %s.\n", &temporal[0].codigo[0]);
  printf("  | Nome: %s.\n", &temporal[0].nome[0]);
  printf("  | Idade: %hu.\n", temporal[0].idade);
  printf("  | Notas: %.2f, %.2f e %.2f.\n", temporal[0].notas[0], temporal[0].notas[1], temporal[0].notas[2]);
  printf("  | Nota final: %.0f.\n",temporal[0].notafinal);
  
  // Libérase a memoria dinámica reservada:
  free(temporal);
  
  // Saída correcta da función:
  return;
}