I'm trying to test the call to a C (edit distance) function in Python, to compare the execution time with a similar function written in Python, it's pure curiosity and a way to understand the C/Python articulation.
Here the implementation of the Levenshtein distance in C (source : wikibooks) in _distance.c file :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int min(int a, int b, int c)
{
if(a <= b && a <= c)
{
return a;
}
else if(b <= a && b <= c)
{
return b;
}
else if(c <= a && c <= b)
{
return c;
}
}
int levenshtein(char *s1, char *s2) {
unsigned int x, y, s1len, s2len;
s1len = strlen(s1);
s2len = strlen(s2);
unsigned int matrix[s2len+1][s1len+1];
matrix[0][0] = 0;
for (x = 1; x <= s2len; x++)
matrix[x][0] = matrix[x-1][0] + 1;
for (y = 1; y <= s1len; y++)
matrix[0][y] = matrix[0][y-1] + 1;
for (x = 1; x <= s2len; x++)
for (y = 1; y <= s1len; y++)
matrix[x][y] = min(matrix[x-1][y] + 1, matrix[x][y-1] + 1, matrix[x-1][y-1] + (s1[y-1] == s2[x-1] ? 0 : 1));
return(matrix[s2len][s1len]);
}
Then I created a _distance.so file, and I call my function as follows :
from ctypes import *
so_file = './_distance.so'
dll = cdll.LoadLibrary(so_file)
# source text
reference = """
Ne vous défiez jamais de votre voisin de gauche qui a une chemise de grosse toile, une cravate blanche, un habit propre,
mais de drap commun ; suivez plutôt très-attentivement les mouvemens de ce voisin de droite, dont la cravate est bien
mise et fine, qui a de grosses breloques, des favoris, un air d’honnête homme, le parler hardi ;
c’est celui-là qui vous volera votre mouchoir ou votre montre.
"""
# target text with errors
hypothesis = """
Ne NOOOS défiez jamais de votre voisin de Gauche qui a une chemises de grosse toile, une cravate blanche, un habit propre,
mais de drap commun ; suivre plu très-attentivement les Mouvemens de ce voisin de droite, dont la cravate est bien
mise et fine, qui a de grosses breloques.
"""
print(dll.levenshtein(reference, hypothesis))
which returns me 0 as a result, while i will have to recover 132 (The result of my Python function).
I can't figure out if this is from the C code, the type of input variables to dll.levenshtein (), or an error in using ctypes package?
thank you very much for your help
[EDIT]
I tested my levenshtein() function in C code directly:
int main()
{
char *ref = "Ne vous défiez jamais de votre voisin de gauche qui a une chemise de grosse toile, une cravate blanche, un habit propre,",
*target = "Ne NOOOS défiez jamais de votre voisin de Gauchate blanche, un habit propre,";
int result;
result = levenshtein(ref, target);
printf("%i", result);
return result;
}
and I have an output with a result.
So I think this came from my call in Python code.
Python string is not char* in C, which points bytes, especially if you are using Python 3.
You should convert a Python string to bytes before you pass it to C.
# source text
reference = """
...
""".encode('utf-8')
# target text with errors
hypothesis = """
...
""".encode('utf-8')
When I compare 2 strings in the website "online gdb", if the comparison is equal it gives 10, if it's not it doesn't give 10(It's already weird that it gives 10 instead of 0, but it works so I didn't care). But since I tried to compile my code with g++ or gcc(I tried with -g too for both)it gives -1 or 1, or only 1, but never 0. Thanks to everyone which will read this code and will help me.
#include <stdio.h>
#include <math.h>
#include <string.h>
int main()
{
char v1q[55], v2q[55], v3q[55], v4q[55];
float v1, v2, v3, v4, vr, min, max;
int comparison;
int v3b = 1;
printf("Per la prima banda non esiste l'oro e l'argento;\nPer la seconda banda non esiste l'oro e l'argento;\nPer la terza banda non esiste il bianco;\nPer la quarta banda esistono SOLO il bianco, oro e argento.\n\n");
printf("Prima cifra: ");
fgets(v1q, sizeof(v1q), stdin);
if(strcmp(v1q, "nero") == 0)
{
printf("\nNon esiste un valore per il nero, per la prima banda");
}
if(strcmp(v1q, "marrone") == 0)
{
v1 = 10;
}
if(strcmp(v1q, "rosso") == 0)
{
v1 = 20;
}
if(strcmp(v1q, "arancione") == 0)
{
v1 = 30;
}
if(strcmp(v1q, "giallo") == 0)
{
v1 = 40;
}
if(strcmp(v1q, "verde") == 0)
{
v1 = 50;
}
if(strcmp(v1q, "blu") == 0)
{
v1 = 60;
}
if(strcmp(v1q, "viola") == 0)
{
v1 = 70;
}
if(strcmp(v1q, "grigio") == 0)
{
v1 = 80;
}
if(strcmp(v1q, "bianco") == 0)
{
v1 = 90;
}
if(strcmp(v1q, "oro") == 0)
{
printf("\nNon esiste un valore per l'oro, per la prima banda");
}
if(strcmp(v1q, "argento") == 0)
{
printf("\nNon esiste un valore per l'argento, per la prima banda");
}
comparison = strcmp(v1q, "marrone");
printf("%d", comparison);
}
In the end I just replaced fgets with scanf, and now it works... I don't know why I didn't do that from the start
A few years ago, when Benoit Mandelbrot died, I decided to make a small program to calculate and see his famous fractal set. I did it many years ago before (with turbo pascal language) - At this period, the calculus took one night. So I decided to learn a little of C language. With code::blocks and the SDL Library (and many helps), I finally wrote a program were I could see the set, and zoom inside with my mouse.
It worked good, I was under windows. Instead of one night of calculus, it took 5 seconds to do the same job.
Recently I decided to discover linux, installed the same IDE with the SDL,. The program is compiling OK. It begins to run, and suddenly, when I use the mouse (left-clic up and down to select the new squared area where to zoom in), the program stops.
The message is :
double free or corruption (!prev)
The strange thing is that it never happened when I ran the code under windows. So here is a mysterious thing for me. I don't know what means double free or corruption here.
For a better help you could eventually send me, I join the code of the program (not perfect). Maybe someone could find where the problem is ...
The program was writen to be seen on a 1680x1050 pxl screen.
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <SDL/SDL.h>
//#include <SDL/SDL_ttf.h>
#define MAXITERATIONS 2000
#define CONST_DIVERGENCE 4
#define LONGUEUR_ECRAN 1680 //ajout d'une zone d'information et d'interaction de 630 pixels de large à droite de l'image.
#define LARGEUR_ECRAN 1050 // côté du carré où l'image est calculée.
int i , j ; /* i variable écran qui parcourt les abscisses entre 0 et LARGEUR_ECRAN
j les ordonnées entre 0 et LARGEUR_ECRAN */
int n ,t ; // itérations pour le calcul de convergence
int color,color1,color2,color3 ; //variable pour la couleur
int continuer = 1;
int recalculer = 1;
int recommencer = 1;
double XDEBUT = -2.05; // coordonnées du point de départ en haut à gauche du carré du plan complexe
double YDEBUT = -1.35;
double DELTA = 2.7 ; // longueur du côté du carré du plan complexe au départ
double xC =0 , yC = 0 ; // coordonnées du point du plan où on effectue les calculs
double xZ , yZ ; // coordonnées pour le calcul de la convergence
double xT = 0 ; // valeur temporaire d'allocation
double xTemp1 =0, yTemp1 = 0 ;
double xTemp2 =0, yTemp2 = 0 ;
int xTemoinDebut =1065; //variables pour positionner les cadres dans le Mandel témoin
int yTemoinDebut =15; //
int deltaTemoin =600; //
int x_1 , y_1; //variables pour positionner le cadre de zoom dans le grand Mandel
int x_2 , y_2; //
int xdebut , ydebut ; //
int delta; //
void placerPoint(SDL_Surface *surface, int x, int y, Uint32 pixel);
void petitMandel ();
int main(int argc, char *argv[])
{
while (recommencer == 1)
{
recommencer = 0;
recalculer =1;
continuer =1;
double XDEBUT = -2.05; // coordonnées du point de départ en haut à gauche du carré du plan complexe
double YDEBUT = -1.35;
double DELTA = 2.7 ; // longueur du côté du carré du plan complexe au départ
int xTemoinDebut =1065; //variables pour positionner les cadres dans le Mandel témoin
int yTemoinDebut =15; //
int deltaTemoin =600; //
double xC =0 , yC = 0 ; // coordonnées du point du plan où on effectue les calculs
double xZ , yZ ; // coordonnées pour le calcul de la convergence
double xT = 0 ; // valeur temporaire d'allocation
double xTemp1 =0, yTemp1 = 0 ;
double xTemp2 =0, yTemp2 = 0 ;
double tableauX [LARGEUR_ECRAN]= {0}; //tableau pour enregistrer les coordonnées réelles où on calcule
double tableauY [LARGEUR_ECRAN] = {0}; //
SDL_Init(SDL_INIT_VIDEO);
SDL_Surface *ecran = NULL,*rectangle=NULL/*,*texte = NULL*/;
// SDL_Event event;
SDL_Rect position;
ecran = SDL_SetVideoMode(LONGUEUR_ECRAN,LARGEUR_ECRAN, 32, SDL_HWSURFACE | SDL_FULLSCREEN); // mode vidéo : écran complet
SDL_LockSurface(ecran);
// SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0)); // remplissage de l'écran en noir
// TTF_Font *police = NULL;
// SDL_Color couleurBleue = {0,0,255};
// TTF_Init();
// test d'erreur d'initialisation
/* if (TTF_Init () == -1)
{
fprintf(stderr, "Erreur d'initialisation de TTF_Init : %s \n",TTF_GetError ());
exit (EXIT_FAILURE);
}*/
/* TTF_Font *police = NULL;
SDL_Color couleurBleue = {0,0,255};
police = TTF_OpenFont("ankecall.ttf",20); police = TTF_OpenFont ("angelina.ttf",65);
texte = TTF_RenderText_Blended (police, "Voyage chez Mandelbrot ", couleurBleue);
while (continuer)
{
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
break;
}
position.x = 1060;
position.y = 630;
SDL_BlitSurface (texte, NULL, ecran, &position);
SDL_Flip(ecran);
}
SDL_FreeSurface(texte);
TTF_CloseFont(police);
TTF_Quit ();
*/
petitMandel(); //commande pour calculer un petit mandel témoin et un trait rouge
while (recalculer == 1)
{
for ( j = 0 ; j < LARGEUR_ECRAN ; j ++) // balayage vertical
{
yC = YDEBUT + (DELTA * j)/LARGEUR_ECRAN;
tableauY[j] = yC;
}
for ( i = 0 ; i < LARGEUR_ECRAN ; i ++) // balayage horizontal
{
xC = XDEBUT + (DELTA * i)/LARGEUR_ECRAN;
tableauX [i] = xC;
}
for ( j = 0 ; j < LARGEUR_ECRAN ; j ++) // balayage vertical
{
yC = YDEBUT + (DELTA * j)/LARGEUR_ECRAN;
for ( i = 0 ; i < LARGEUR_ECRAN ; i ++) // balayage horizontal
{
xC = XDEBUT + (DELTA * i)/LARGEUR_ECRAN;
n = 0 ; // initialisation du compteur de calcul
xZ = 0 ;
yZ = 0 ;
xT = 0 ;
while ( xZ*xZ + yZ*yZ < CONST_DIVERGENCE && n < MAXITERATIONS) /* boucle de calcul
elle s'arretera si xZ²+yZ² >= 4 ou si on a atteint le maximum d'itérations*/
{
xT = xZ ;// variable temporaire pour le calcul de yZ
xZ = xZ*xZ - yZ*yZ + xC ;
yZ = 2*yZ*xT + yC ;
n ++;
}
if (n< MAXITERATIONS) // On est en dehors de l'ensemble : mettre en gris
placerPoint(ecran,i,j,SDL_MapRGB(ecran->format,n,n,n));
else // On est dans l'ensemble : mettre en noir.
placerPoint(ecran,i,j,SDL_MapRGB(ecran->format,0,0,0));
}
}
SDL_UnlockSurface(ecran);
SDL_Flip(ecran);
recalculer = 0;
//Gestion des choix:
SDL_Event event;
while (continuer & (recalculer == 0))
{
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
break;
case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_LEFT) //si clic gauche enfoncé
{
position.x = event.button.x;
position.y = event.button.y;
xTemp1 = tableauX [position.x];
yTemp1 = tableauY [position.y];
x_1 = position.x;
y_1 = position.y;
}
break;
case SDL_MOUSEBUTTONUP:
if (event.button.button == SDL_BUTTON_LEFT) //si clic gauche relaché
{
position.x = event.button.x;
position.y = event.button.y;
xTemp2 = tableauX [position.x];
yTemp2 = tableauY [position.y];
x_2 = position.x;
y_2 = position.y;
if (xTemp1 <xTemp2)
{
XDEBUT = xTemp1;
xdebut = x_1;
}
else
{
XDEBUT = xTemp2;
xdebut = x_2;
}
if (yTemp1<yTemp2)
{
YDEBUT = yTemp1;
ydebut = y_1;
}
else
{
YDEBUT = yTemp2;
ydebut = y_2;
}
if (fabs(xTemp1-xTemp2)<fabs(yTemp1-yTemp2))
{
DELTA = fabs(yTemp1-yTemp2);
delta = fabs(y_1-y_2);
}
else
{
DELTA = fabs(xTemp1-xTemp2);
delta = fabs(x_1-x_2);
}
// dessin du cadre blanc pour zoomer dans l'image principale
rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, delta, 32, 0, 0, 0, 0); // Allocation du point
position.x = xdebut ; // Coordonnées du point à placer
position.y = ydebut ;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);
rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE,delta, 1, 32, 0, 0, 0, 0); // Allocation du point
position.x = xdebut ; // Coordonnées du point à placer
position.y = ydebut ;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);
rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, delta, 32, 0, 0, 0, 0); // Allocation du point
position.x = xdebut + delta; // Coordonnées du point à placer
position.y = ydebut ;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);
rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE, delta, 1, 32, 0, 0, 0, 0); // Allocation du point
position.x = xdebut ; // Coordonnées du point à placer
position.y = ydebut + delta;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);
//dessin du cadre dans le mandelbrot témoin
xTemoinDebut = floor(xdebut*deltaTemoin/1050) + xTemoinDebut;
yTemoinDebut = floor(ydebut*deltaTemoin/1050) + yTemoinDebut;
deltaTemoin = floor(delta*deltaTemoin/1050);
rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, deltaTemoin, 32, 0, 0, 0, 0); // Allocation du point
position.x = xTemoinDebut ; // Coordonnées du point à placer
position.y = yTemoinDebut ;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);
rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE, deltaTemoin, 1, 32, 0, 0, 0, 0); // Allocation du point
position.x = xTemoinDebut ; // Coordonnées du point à placer
position.y = yTemoinDebut ;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);
rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, deltaTemoin, 32, 0, 0, 0, 0); // Allocation du point
position.x = xTemoinDebut + deltaTemoin; // Coordonnées du point à placer
position.y = yTemoinDebut ;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);
rectangle = SDL_CreateRGBSurface(SDL_HWSURFACE, deltaTemoin, 1, 32, 0, 0, 0, 0); // Allocation du point
position.x = xTemoinDebut ; // Coordonnées du point à placer
position.y = yTemoinDebut + deltaTemoin;
SDL_FillRect(rectangle, NULL, SDL_MapRGB(ecran->format, 255,255,255)); // Remplissage du point en gris.
SDL_BlitSurface(rectangle, NULL, ecran, &position); // Collage du point sur l'écran
SDL_Flip(ecran);
SDL_FreeSurface(rectangle);
recalculer = 1;
}
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE)
continuer = 0 ;
if (event.key.keysym.sym == SDLK_r)
{
recommencer = 1 ;
recalculer = 0;
continuer =0;
}
if (event.key.keysym.sym == SDLK_s)
SDL_SaveBMP(ecran , "Mandel_50.bmp" ); // Enregistrement de l'image dans un fichier .bmp
break;
}
}
SDL_FreeSurface(rectangle); // Libération de la surface
}
}
SDL_Quit();
return EXIT_SUCCESS;
}
void petitMandel ()
{
int x=0,y=0;
SDL_Surface *ecran ;
ecran = SDL_GetVideoSurface();
SDL_LockSurface(ecran);
// trait rouge à droite de l'image
for (j=5; j<=1044; j++)
{
x = LARGEUR_ECRAN +5 ;
y = j ;
placerPoint(ecran,x,y,SDL_MapRGB(ecran->format,200,0,0));
}
SDL_Flip(ecran);
// instructions pour placer un petit Mandelbrot témoin dans la fenêtre "interactive"
for ( j = 0 ; j < 600 ; j ++) // balayage vertical
{
yC = YDEBUT + (DELTA * j)/600;
for ( i = 0 ; i < 600 ; i ++) // balayage horizontal
{
xC = XDEBUT + (DELTA * i)/600;
n = 0 ; // initialisation du compteur de calcul
xZ = 0 ;
yZ = 0 ;
xT = 0 ;
while ( xZ*xZ + yZ*yZ < CONST_DIVERGENCE && n < 500) /* boucle de calcul
elle s'arretera si xZ²+yZ² >= 4 ou si on a atteint le maximum d'itérations*/
{
xT = xZ ;// variable temporaire pour le calcul de yZ
xZ = xZ*xZ - yZ*yZ + xC ;
yZ = 2*yZ*xT + yC ;
n ++;
}
if (n< 500)
{
x = i + 1065 ; // Coordonnées du point à placer
y = j + 15;
color = floor (255-255*log(1+n*255/500)/log(256)); // calcul pour un dégradé plus progressif*/
placerPoint(ecran,x,y,SDL_MapRGB(ecran->format,color,color,color));
}
}
}
SDL_UnlockSurface(ecran);
SDL_Flip(ecran);
}
void placerPoint(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp)
{
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
{
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
}
else
{
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
Looks like you're freeing your SDL_Surface pointer "rectangle" once extra on line 309. If you comment that line out it runs fine.
When the code gets into the "SDL_MOUSEBUTTONUP" case of your switch statement, it frees the rectangle, then on line 309 it's freed again.
You are overrunning tableauX (and possibly tableauY, if given a chance). Put asserts before them:
assert(j < LARGEUR_ECRAN);
tableauY[j] = yC;
Put an assert before all accesses (there are 6 in your program).
I did this and the following assertion failed
assert(position.x < LARGEUR_ECRAN)
xTemp1 = tableauX [position.x];
That the assertion failed means that position.x is >= LARGEUR_ECRAN. In fact it was 1243, whereas LARGEUR_ECRAN is 1050. Note that the failure will not necessarily occur on the first out-of-bounds access, which is why it didn't happen as soon as position.x reached 1050.
Also note that it's possible to run "successfully" (even with the bug) on one system while crashing on another.
EDIT: Actually, user5071535 seems to have found a more likely source for your error message, but I may have uncovered a different bug here.
Every free() on unallocated pointer or in a pointer different of NULL will return this error. Certify yourself if pointer its already allocated or is equal to NULL before any try of free(). Anyway, any try to work in an unallocated pointer or improperly/insufficient allocated will return this error. The fact of under Windows the things happens differently, its only a question of "lucky": Bad codes will fail at any plattform on an "random" time inevitably. Sorry for bad english.
I am trying to create a program in C that takes in any date and returns the zodiac sign.I have a function that is supposed to validate if the date is possible (day >0,month>0, if month ==x ,day <31 etc ) Thing is that on the part where it is supposed to validate the month and determine if it is a 30 month or a 31 month it only accepts one part of the conditions making it either a definite 30 day for all months or a 31 day for all months.
the function name is fnValidacion()
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
/*
Programa : Signo Zodiaco.
Autor : Samir Fersobe 1063021
Fecha : Marzo 28, 2015
*/
const char *signo[12] = {"Aries","Tauro","Geminis","Cancer","Leo","Virgo","Libra","Escorpio",
"Sagitario","Capricornio","Acuario","Piscis"};//Arreglo de Signos Zodiacales
int Ano,Mes,Dia ;//Variables de Ano , Mes y Dia.
int aprovacion = 0;//Determina si la funcion sigue o no.
int bisiesto = 1 ;//determina si el año es bisiesto.
int type ;//determina la estacion.
//Funciones
void fnFecha() ;//Consigue la fecha
void fnBisiesto() ;//Define si el año es bisiesto.
void fnValidacion();//Determina si la fecha es valida.
void fnSigno() ;//Determina el signo zodiacal.
void fnDevuelta() ;//Devuelve la respuesta.
int main(int argc, char** argv)
{
fnFecha();
fnBisiesto();
fnValidacion();
fnSigno();
fnDevuelta();
}
void fnDevuelta()
{/*determinar si la funcion sigue o no, y devuelve el resultado al usuario */
switch (aprovacion){
case 1:
printf("El Signo Zodiacal es %s",signo[type]);
break;
default:
printf("\n Intente de nuevo con otra fecha.");
break;
}
}
void fnSigno()
{/*Determina el signo zodiacal*/
switch(Mes){
case 12:
if (Dia < 22)
type = 8;
else
type = 9;
break;
case 1:
if (Dia < 20)
type = 9;
else
type = 10;
break;
case 2:
if (Dia < 18)
type = 10;
else
type = 11;
break;
case 3:
if (Dia < 20)
type = 11;
else
type = 0;
break;
case 4:
if (Dia < 20)
type = 0;
else
type = 1;
break;
case 5:
if (Dia < 21)
type = 1;
else
type = 2;
break;
case 6:
if (Dia < 21)
type = 2;
else
type = 3;
break;
case 7:
if (Dia < 23)
type = 3;
else
type = 4;
break;
case 8:
if (Dia < 28)
type = 4;
else
type = 5;
break;
case 9:
if (Dia < 23)
type = 5;
else
type = 6;
break;
case 10:
if (Dia < 23)
type = 6;
else
type = 7;
break;
case 11:
if (Dia < 22)
type = 7;
else
type = 8;
break;
}
}
void fnBisiesto()
{/*determina si el ano es bisiesto */
if ((Ano%4 != 0) || ((Ano%100 == 0) && (Ano%400 != 0)))
bisiesto = 0;
}
void fnValidacion()
{/*Esta parte determina si la fecha es valida*/
if (
(Ano < 0) || (Dia <0) || (Mes < 1) || (Mes > 12) ||//Ano,Dia,Mes No negativo.Mes entre 1 y 12.
(Dia > 31) || ((Mes == 4,6,9,11) && (Dia > 30)) ||//Dia no mayor que 31.Si mes es de 30, Dia no mayor que 30.
((bisiesto == 0) && (Mes == 2) && (Dia > 28)) ||//Si no es bisiesto febrero no mayor que 28.
((bisiesto == 1) && (Mes == 2) && (Dia > 29)) //Si es bisiesto febrero no mayor que 29.
)
printf("Esta fecha no es Valida."); //Explica al usuario que fecha no es valida.
else
return aprovacion = 1;
}
void fnFecha()
{/*Adquiere la fecha del usuario */
printf("Inserte el Ano: ");
scanf("%d", &Ano);
printf("Inserte el Mes: ");
scanf("%d", &Mes);
printf("Inserte el Dia: ");
scanf("%d", &Dia);
return ;
}
I think, your problem is in
(Mes == 4,6,9,11)
You have to write all the conditions individually, maybe something like
((Mes == 4) || (Mes == 6) || (Mes == 9) || (Mes ==11))
Otherwise, as per the operator precedence, your code will look like
((Mes == 4), 6,9,11)
where (Mes == 4) producing either 0 or 1. Next, as per the , operator property, <#>
The left operand of a comma operator is evaluated as a void expression; there is a
sequence point between its evaluation and that of the right operand. Then the right
operand is evaluated; the result has its type and value.
So, finally, your expression becomes (11), which is a true value for if condition or logical operator.
[#Quoted from C11 standard, chapter §6.5.17].