LINGUAGEM: Linguagem C - Capítulo 2 - Parte 5

Exemplo: Lista de Strings

Dado o código abaixo (que pode ser obtido como projeto Dev-Cpp neste link), complemente o código do arquivo lista.c escrevendo as funções:
  • list_rem()
  • list_get()
  • list_set()

main.c

/* main.c **/

#include <stdio.h>
#include <stdlib.h>
#include "list.h"
#include "xcpt.h"

int main(int argc, char *argv[])
{
  while (1) {
        char str[1024];
        int  pos;
 const char * xc;
        
        printf("\nAdicionar\n");
        
        printf("  pos = "); scanf("%d",&pos);
        printf("  str = "); gets(str); gets(str);

        list_add(str,pos);
/*
        TRY(list_add(str,pos));
        
        CATCH(INDEX_OUT_OF_BOUNDS_XCPT,xc)
           printf("\npos invalida!\n");

        CATCH(LIST_FULL_XCPT,xc)
           printf("\nlista cheia!\n");

        CATCH(LINE_TOO_LONG_XCPT,xc)
           printf("\nstr muito grande!\n");
*/
        printf("\nLista\n");
        list_print();
       
  }  
}

list.h, list.c

/* list.h, Rev. 1.1
   (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br>
   
   Implements a list of strings.
**/

#ifndef LIST_H
#define LIST_H

#define LIST_MAX_SIZE      99
#define LINE_MAX_SIZE      60

#define LIST_FULL_XCPT     "list full"
#define LINE_TOO_LONG_XCPT "line too long"

unsigned short list_size(void);

void    list_add(const char * str, unsigned short pos);
char *  list_rem(unsigned short pos);
void    list_set(const char * str, unsigned short pos);
char *  list_get(unsigned short pos);

void    list_print(void);

#endif

/* list.c, Rev. 1.1
   (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br>
   
   Implements a list of strings.
**/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "list.h"
#include "xcpt.h"

/** private data */
static  char list[LIST_MAX_SIZE][LINE_MAX_SIZE+1];
static  unsigned short  size = 0;

static  char xcpt_cmsg[XCPT_CMSG_MAX_SIZE+1];

/** public functions */

unsigned short list_size(void) {
        return size;
}

/*
  Add a new element str in the list at a given position pos.
  From pos to the end of the list, all existing elements are
  shifted right.
  
  Throws:
         INDEX_OUT_OF_BOUNDS_XCPT  when pos is invalid ( > size +1 )
         LIST_FULL_XCPT            when the list size equals LIST_MAX_SIZE
         LINE_TOO_LONG_XCPT        when str is greater than  LINE_MAX_SIZE
**/
void    list_add(const char * str, unsigned short pos) {
        
        sprintf(xcpt_cmsg,"@%s[%d]\n> list_ins (\"%s\",%d);\n",
    __FILE__,__LINE__,str,pos);

        if ( pos > size + 1 ) {
             THROW(INDEX_OUT_OF_BOUNDS_XCPT,xcpt_cmsg);
             return ;
        }
        
        if ( size + 1 > LIST_MAX_SIZE ) {
             THROW(LIST_FULL_XCPT,xcpt_cmsg);
             return ;
        }

        if ( strlen(str) > LINE_MAX_SIZE ) {
             THROW(LINE_TOO_LONG_XCPT,xcpt_cmsg);
        }
                
        if ( pos == 0 ) {
             strncpy(list[size],str,LINE_MAX_SIZE);
        } else {  
             int  i;

             for ( i = size ; i >= pos; i-- )
                 strcpy(list[i],list[i-1]);
             
             strncpy(list[i],str,LINE_MAX_SIZE);
        }
        size++;
}

char *  list_rem(unsigned short pos) {
}

void    list_set(const char * str, unsigned short pos) {
}

char *  list_get(unsigned short pos) {
}

void list_print(void) {     
     int i;
     
     for ( i=0; i < size; i++ )
         printf("%2d: %s\n",i+1,list[i]);

}

xcpt.h, xcpt.c

/* xcpt.h, Rev. 1.1
   (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br>
   
   Implements an exception handling mechanism inspired in Java.
**/
#ifndef XCPT_H
#define XCPT_H

#define XCPT_NAME_MAX_SIZE   32
#define XCPT_CMSG_MAX_SIZE   1024

#define THROW(e,m)   __throw((e),(m))
#define TRY(f)     __begin_try();f;__end_try();
#define CATCH(e,m)   if(m=__catch(e))

#define NULL_POINTER_XCPT               "null pointer"
#define INDEX_OUT_OF_BOUNDS_XCPT        "index out of bounds"
#define OVERFLOW_XCPT                   "overflow"
#define UNDERFLOW_XCPT                  "underflow"
#define ILLEGAL_ARGUMENT_XCPT           "illegal argument" 

void            __begin_try(void);
void            __end_try(void);
const char *    __catch(const char *name);
void            __throw(const char *name, const char *cmsg);

#endif

/* xcpt.c, Rev. 1.1
   (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br>
   
   Implements an exception handling mechanism inspired in Java.
**/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "xcpt.h"


static char xcpt_name[XCPT_NAME_MAX_SIZE + 1];
static char xcpt_cmsg[XCPT_CMSG_MAX_SIZE + 1];

static int trying;

/*
  Sets try_flag.
**/
void __begin_try(void) {
     trying = 1;
}

/*
  UnSets try_flag.
**/
void __end_try(void){
     trying = 0;
}

/*
  From exception name, gets the exception message thown by
  __throw(n,m). Once cautch, the exception name is cleared .
**/
const char * __catch(const char * name) {
      if ( strcmp(xcpt_name,name) == 0 ) {
         xcpt_name[0] = '\0';
         return xcpt_cmsg;
      }
      else
         return NULL;
}

/*
  Stores an exception contextual message.  
  When called outside a __begin_try(); ...; __end_try(); pair,
  the exception message is also printed to the stderr stream .
**/
void __throw(const char * name,const char * cmsg) {
     strncpy(xcpt_name,name,XCPT_NAME_MAX_SIZE);
     strncpy(xcpt_cmsg,cmsg,XCPT_CMSG_MAX_SIZE);
     
     if ( !trying )
          fprintf(stderr,"exception: %s: %s\n",xcpt_name,xcpt_cmsg);
}
Bibliografia e fonte:

  • [CCT] Schildt, H. (1996) C, completo e total: 3a Ed.. São Paulo, Makron.
  • LP, UFMA; Coutinho, Lucian. Linguagem de programação para ciencia da computação da ufma.http://www.deinf.ufma.br/~lrc/2009.1/LP/
  • [K&R] KERNIGHAN, B. e RITCHIE, D. (1990) C, a linguagem de programação: padrão ANSI. Rio de Janeiro: Campus.
  • DEITEL, H. M. (1999) Como programar em C. Rio de Janeiro: LTC.
  • Módulo Consultoria e Informática (1989) Linguagem C: programação e aplicações. Rio de Janeiro: LTC.