Autor
|
Tema: [ANSI C] Split(), strlen(), mid(), Instr(), strcpy(). (Leído 10,253 veces)
|
BlackZeroX
Wiki
Desconectado
Mensajes: 3.158
I'Love...!¡.
|
. Esta es la version de split() ya esta corregida debugeada y sirve en todo caso. Quien no sepa usar Vectores en C esta muerto ( ** ), es decir Puntero a Puntero. Corregido por segunda vez: #include<stdlib.h> #include<stdio.h> #ifndef bool typedef enum bool { false, true } bool; #endif unsigned int rectific_num(unsigned int vval,unsigned int vmin,unsigned int vmax); bool fix_numbers_range(unsigned int* vIndexIni,unsigned int* vIndexEnd, unsigned int* vLen, unsigned int vMin, unsigned int vMax); unsigned long strlen(char* string ); unsigned long instr(unsigned long start,char* string1,char* string2); char* mid(char* str, unsigned int start, unsigned int len); char* strcpy(char* str_dest ,char* str_src ); char** split(char* str, char* delimiter, long* limit); int main() { long lim=-1; long i=0; char **array = split((char*)".Este.es.Hola.Mundo.Hola.mundo.",(char*)".",&lim); if ( array != 0 ) { for ( i=0 ; i <= lim ;i++ ) { printf("%d\t%s\n",i ,array [i ]); } } return 0; } unsigned int rectific_num(unsigned int vval,unsigned int vmin,unsigned int vmax) /** Corrige [vVal] con respecto a un minimo y a un maximo valor. By BlackZeroX ( http://Infrangelux.sytes.net/ ) **/ { if (vval < vmin) return vmin; else if ( vval > vmax ) return vmax; else return vval; } bool fix_numbers_range(unsigned int* vIndexIni,unsigned int* vIndexEnd, unsigned int* vLen, unsigned int vMin, unsigned int vMax) /** Corrige los rangos de [vIndexIni],[vIndexEnd], [vLen] con respecto a un minimo y a un maximo valor. [vLen] corresponde a la distancia entre [vIndexIni] y [vIndexEnd]. Se retorna false solo si [vMax] es menor que que [vIndexIni] o que [*vLen] es igual o menor a [0] By BlackZeroX ( http://Infrangelux.sytes.net/ ) **/ { if ( vMax >= *vIndexIni && *vLen != 0 ) { *vIndexIni = rectific_num(*vIndexIni,vMin,vMax); *vIndexEnd = rectific_num(*vIndexIni + *vLen,*vIndexIni,vMax); *vLen= *vIndexEnd - *vIndexIni+1; return ( (*vLen > 0) ? true: false); } else { return false; } } unsigned long strlen(char* string ) /** Retorna la longitud de [string] By BlackZeroX ( http://Infrangelux.sytes.net/ ) **/ { unsigned long i=0; while (*(string++)) i++; return i; } char* strcpy(char* str_dest ,char* str_src ) /** Copia [*str_src] a [*str_dest]. Retorna el puntero a [str_dest] By BlackZeroX ( http://Infrangelux.sytes.net/ ) **/ { char *copyreturn = str_dest; while(*(str_dest++)=*(str_src++)); return copyreturn; } unsigned long instr(unsigned long start,char* string1,char* string2) /** [Start] indica la posicion inicial donde se empesara a buscar en [string1] Retorna la posicion de [*string2] en [*string1]. By BlackZeroX ( http://Infrangelux.sytes.net/ ) **/ { unsigned long q,c,limit; q=c=limit=0; long ls2len=0; if ( ls2len >= 0 ) { limit = strlen(string1 )-ls2len ; if ( limit > 1 ) { q = start-1; while ( q < limit ) { while ( string1[q+c] == string2[c] ) if ( (c++) == (unsigned long)ls2len ) return q+1; q+=c+1; c=0; } } } else if (*string1 > '\0') { return 1; } return 0; } char* mid(char* str, unsigned int start, unsigned int len) /** Se obtiene el fragmento deseado de [*str] [Start] Indica desde donde se empesara [Len] Indica la distancia. Retorna el puntero al clon del fragmento deseado de [*str] By BlackZeroX ( http://Infrangelux.sytes.net/ ) **/ { char* pch_t = 0; unsigned int ul_str =strlen(str ); unsigned int ul_end=start+len; start--; if ( fix_numbers_range(&start,&ul_end,&len,0,ul_str) == true ) { if ( (pch_t = (char*)malloc(sizeof(char)*len )) != 0 ) { for (ul_str=0;ul_str < (len-1) ;start++,ul_str++ ) pch_t[ul_str] = str[start]; pch_t[len-1]='\0'; } } else { if ( (pch_t = (char*)malloc(sizeof(char))) != 0 ) pch_t[0]='\0'; } return pch_t; } char** split(char* str, char* delimiter, long* limit) /** Separa a [*str] cada vez que se encuentre a [*delimiter] con un limite definido en [*limit] Si [*limit] = -1 se crea un Maximo mayor a [-1] en el indice del vector retornado Si [*limit] > -1 Se indica y establece un indice mayor [pero no fijo] del indice mayor del vector retornado En ambos casos [*limit] retorna el Indice maximo del vector retornado por la funcion y la funcion retorna el puntero a el vector retultante. En casos contrarios no crea un vector y retorna 0 y [*limit] = [-1] By BlackZeroX ( http://Infrangelux.sytes.net/ ) **/ { unsigned int ui_lp =1; unsigned int ui_inc =1; unsigned int ui_lns =0; unsigned int ui_del =0; unsigned long ui_ub =0; char **pi_out =0; if ( *limit >= -1 ) { delimiter = (char*)" "; pi_out = (char**)malloc(sizeof(char*)); for(;pi_out!=0;) { if ( ui_ub == *limit ) { pi_out[ui_ub] = mid(str, ui_lp,ui_lns); ui_ub = *limit; break; } ui_inc = instr(ui_inc, str, delimiter); if ( ui_inc == 0 ) { pi_out[ui_ub] = mid(str, ui_lp,ui_lns); break; } pi_out[ui_ub] = mid(str, ui_lp, ui_inc - ui_lp); pi_out = (char**)realloc(pi_out ,sizeof(char*)*(++ui_ub +1)); ui_lp = ui_inc + ui_del; ui_inc = ui_lp; } *limit = ui_ub; return pi_out; } *limit=-1; return 0; }
Nota.: Si alguien ve algun fallo por favor de no golpearme gracias!¡. Temibles Lunas!¡.
|
|
« Última modificación: 14 Enero 2011, 07:45 am por BlackZeroX▓▓▒▒░░ »
|
En línea
|
The Dark Shadow is my passion.
|
|
|
Littlehorse
All the world's a stage
Moderador
Desconectado
Mensajes: 2.714
Nie Dam Sie
|
El propósito de los comentarios es aclarar el código y no lo contrario. Si quieres poner créditos los puedes agregar al principio, pero poner spam en los comienzos de cada función sinceramente invitan a no seguir leyendo el código.
Por otro lado, el tipo de dato bool no existe en C, solo en C++, y viendo que estas utilizando las cabeceras de C, deberías definir el tipo de dato bool por tu cuenta. No he leido el resto del código; utilizar typedefs ayuda a que el código sea mas comprensible a primera vista.
Saludos
|
|
|
En línea
|
An expert is a man who has made all the mistakes which can be made, in a very narrow field.
|
|
|
leogtz
. . .. ... ..... ........ ............. .....................
Colaborador
Desconectado
Mensajes: 3.069
/^$/
|
Siempre retornas 1 en el main() eso es incorrecto, para el sistema operativo tu programa no funciona bien. unsigned long strlen(char* string ) { unsigned long i=0; while (*string++) i++; return i; }
|
|
« Última modificación: 13 Enero 2011, 01:33 am por Leo Gutiérrez. »
|
En línea
|
|
|
|
BlackZeroX
Wiki
Desconectado
Mensajes: 3.158
I'Love...!¡.
|
. Les agradezco sus comentarios pero acabo de ver un error, y ahorita solo me intriga que me salte este error. int main() { long lim=-1; long limback=lim; char **array = split((char*)"Este es un hola mundo desde InfrAngeluX-Soft",(char*)"u",&lim); if ( array != 0 ) { limback=lim; for (; lim>-1 ;lim-- ) printf ("%d \t %s \n", lim , array [lim ] ); for (; limback>0 ;limback-- ) } return 0; }
Heap block at 003E1750 modified at 003E175E past requested size of 6
Nota: seguire viendo por que me salta... Dulces Lunas!¡.
|
|
« Última modificación: 13 Enero 2011, 01:48 am por BlackZeroX▓▓▒▒░░ »
|
En línea
|
The Dark Shadow is my passion.
|
|
|
Psyke1
Wiki
Desconectado
Mensajes: 1.089
|
Hola Black! Parece que te estás pasando ya a Cpp eh? Me gusta tu función Instr(), me recuerda a la que hice yo hace días en vb6 : unsigned long instr(unsigned long start,char* string1,char* string2) /* [Start] indica la posicion inicial donde se empesara a buscar en [string1] Retorna la posicion de [*string2] en [*string1]. By BlackZeroX ( http://Infrangelux.sytes.net/ ) */ { unsigned long q,c,limit; q=c=limit=0; long ls2len=0; if ( ls2len >= 0 ) { limit = strlen(string1 )-ls2len ; if ( limit > 1 ) { q = start-1; while ( q < limit ) { while ( string1[q+c] == string2[c] ) if ( (c++) == (unsigned long)ls2len ) return q+1; q+=c+1; c=0; } } } else if (*string1 > '\0') { return 1; } return 0; }
Option Explicit Option Base 0 Private Function myInstr&(ByVal Start&, ByVal String1$, ByVal String2$) Dim bvString1() As Byte, bvString2() As Byte Dim ls2Len&, lLimit& Dim Q&, C& ls2Len& = ((Len(String2$)) - &H1) If ls2Len& > -1 Then lLimit& = ((Len(String1$)) - ls2Len&) If lLimit& > 1 Then bvString1 = (VBA.StrConv(String1$, vbFromUnicode)) bvString2 = (VBA.StrConv(String2$, vbFromUnicode)) Q& = (Start& - &H1) Do While (Q& < lLimit&) Do While (bvString1(Q& + C&) = bvString2(C&)) 'Debug.Print ChrW$(bvString1(Q& + C&)); ChrW$(bvString2(C&)) C& = C& + &H1 If ((C& - &H1) = ls2Len&) Then myInstr& = Q& + &H1 Exit Function End If Loop Q& = (Q& + C&) + &H1 C& = &H0 Loop End If End If End Function
http://goo.gl/Pv2Be Un día de estos que no estés ocupado te tengo que preguntar dudas por msn... DoEvents!
|
|
|
En línea
|
|
|
|
BlackZeroX
Wiki
Desconectado
Mensajes: 3.158
I'Love...!¡.
|
. Ya corregi el error el problema era con la funcion mid(), TODO ya funciona como deberia de ser.
@ Leo Gutiérrez. Puse la comparacion con el caracter nulo solo para tener la menor cantidad de advertencias de mi IDE/Compilador.
P.D.: Si Rana es el mismo solo que lo tube que traducir, fue la que mas me gusto.
Dulces Lunas!¡.
|
|
« Última modificación: 13 Enero 2011, 02:22 am por BlackZeroX▓▓▒▒░░ »
|
En línea
|
The Dark Shadow is my passion.
|
|
|
08l00D
Desconectado
Mensajes: 168
|
Por otro lado, el tipo de dato bool no existe en C, solo en C++ Saludos
En realidad si existe en C.. se implemento a partir del estandar C99.. se puede utilizar como _Bool ... o bool (incluyendo <stdbool>, donde esta definido) aunque igual siempre es mejor definirlo para no joder la compatibilidad con compiladores viejos.. unsigned long strlen(char* string ) /** Retorna la longitud de [string] By BlackZeroX ( http://Infrangelux.sytes.net/ ) **/ {//no esta mal pero deberias restarle 1 a i antes de retornarla asi no incluye el valor te terminador de cadena, asi el que use tu implementacion de la funcion no tenga que restarle 1 al valor cada vez que la use... unsigned long i=0; while (*(string++) != '\0') i++; return i; } char* strcpy(char* str_dest ,char* str_src ) /** Copia una string a otra [*str_src] a [*str_dest]. Retorna el puntero a [str_dest] By BlackZeroX ( http://Infrangelux.sytes.net/ ) **/ { while( (*(str_dest++)=*(str_src++) == '\0' ) ); // MAL... la comparacion esta mal .. tenes que comparar si la cadena es distinta a '\0' no igual.... cuando copias tambien esta mal ... ya que estarias copiando el resutado de la comparacion ..la precedencia del operador == es mayor al de asignacion... necesitas parentesis.. return (str_dest); }
Por lo demas no lo vi en detalle ... pero vi que los punteros devueltos por malloc los comparas por 0 .. lo cual en teoria no esta mal ya que el compilador se da cuenta que el 0 esta siendo utilizada en un contexto de puntero y hace la conversion a NULL implicitamente.. pero no es una buena practica en C... utiliza siempre NULL.. al igual que cuando inicialices tus punteros... ah y otra cosa cuando tenes una expresion como *cadena++ los parentesis no son necesarios ... el operador ++ tiene mayor precedencia que el de desreferencia... Saludos
|
|
|
En línea
|
|
|
|
Littlehorse
All the world's a stage
Moderador
Desconectado
Mensajes: 2.714
Nie Dam Sie
|
En realidad si existe en C No, en C++ bool es un tipo de dato primitivo aparte. En C, desde C99 como bien decís, se define mediante macros en stdbool.h, pero es al día de hoy que se sigue definiendo aparte no solo por retrocompatibilidad, también por claridad de código. pero no es una buena practica en C... utiliza siempre NULL.. al igual que cuando inicialices tus punteros... No esta establecido que sea una mala practica no utilizar NULL. Es simplemente una cuestión de estilo que se suele aplicar mas que nada en código critico donde se requiera dejar bien en claro que se esta tratando con punteros, pero no mas que eso. an integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function. Personalmente me molesta bastante leer NULL por todos lados cuando esta mas que claro que se trata de punteros. Si se necesita dejar en claro que es un puntero no me parece mal, pero tampoco exagerar. En C++ directamente es lo contrario, el mismo creador recomienda utilizar 0 en lugar de NULL. Saludos
|
|
« Última modificación: 13 Enero 2011, 20:31 pm por Littlehorse »
|
En línea
|
An expert is a man who has made all the mistakes which can be made, in a very narrow field.
|
|
|
BlackZeroX
Wiki
Desconectado
Mensajes: 3.158
I'Love...!¡.
|
unsigned long strlen(char* string ) /** Retorna la longitud de [string] By BlackZeroX ( http://Infrangelux.sytes.net/ ) **/ {//no esta mal pero deberias restarle 1 a i antes de retornarla asi no incluye el valor te terminador de cadena, asi el que use tu implementacion de la funcion no tenga que restarle 1 al valor cada vez que la use... unsigned long i=0; while (*(string++) != '\0') i++; return i; }
Muchas gracias por "tu corrección", pero por otro lado la funcion y objetivo es colo contar caracteres sin el char NULL por ende esta correcto /* tiene que devolver una longitud de 4 caracteres que es lo que interesa, el '\0' al final no nos interesa. * Salida 4. */
En strcpy() gracias me hiciste ver un error de hecho, y de hecho ni hiba a poner la igualdad a '\0' ( ya que se obvia ) pero como dije arriba solo puse dichas comparaciones para evitar la mayor cantidad de Advertencias que me tiraba mi IDE/Compilador. aun que me tira una de unsigned long y un long ( esta la he estado ignorando ) ya que como se que un long abarca un buen numero..., y por otro lado ya se como se evaluan los operadores unitarios. Gracias por lo de NULL, solo una duda mas si pongo (char*)0 tambien vale?, en mi forma de pensar es correcto pero desearia ver que piensan otros ya que no me deseo encerrar! en una conjetura¡. P.D.: El objetivo de estos codigos para mi es mejorar la comprension, sintaxis ( a tal grado de que ya no use tanto la web tal y como lo hago ya con vb6 q ya puedo hacer codigo de forma fluida usando las APIS del sistema. ), y evitar horrores de sintasys y demás cosas, ¿no voy tan perdido vdd? xP. Dulces Lunas!¡. .
|
|
« Última modificación: 13 Enero 2011, 21:05 pm por BlackZeroX▓▓▒▒░░ »
|
En línea
|
The Dark Shadow is my passion.
|
|
|
Littlehorse
All the world's a stage
Moderador
Desconectado
Mensajes: 2.714
Nie Dam Sie
|
Gracias por lo de NULL, solo una duda mas si pongo (char*)0 tambien vale?, en mi forma de pensar es correcto pero desearia ver que piensan otros ya que no me deseo encerrar! en una conjetura¡. Dependiendo del caso legal es, pero correcto no. Utiliza NULL en casos donde sea importante que el programador detecte a primera vista que se esta tratando de un puntero, para los otros casos puedes usar 0 perfectamente. En el caso de C++, con 0 basta y sobra. #ifndef NULL #ifdef _cpp #define NULL 0 #else /* not cpp */ #define NULL ((void *)0) #endif #endif
Saludos
|
|
|
En línea
|
An expert is a man who has made all the mistakes which can be made, in a very narrow field.
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Problema con funcion strcpy().
Programación C/C++
|
dark-heimdall
|
1
|
4,986
|
19 Febrero 2011, 06:36 am
por dark-heimdall
|
|
|
Duda con strlen [Solucionado]
Programación C/C++
|
Dark00
|
9
|
5,753
|
11 Noviembre 2012, 19:17 pm
por Dark00
|
|
|
[FASM]strlen en ASM
ASM
|
0xDani
|
7
|
5,918
|
28 Diciembre 2012, 14:30 pm
por avesudra
|
|
|
[Micro-rutina] strlen - ANSI
« 1 2 »
ASM
|
Karcrack
|
13
|
8,038
|
4 Abril 2013, 02:14 am
por mr.blood
|
|
|
Crear mis propias funciones que hagan de: strcpy, strlen, strcmp, strcat
Programación C/C++
|
galapok11
|
2
|
3,290
|
12 Agosto 2016, 17:13 pm
por Yoel Alejandro
|
|