If statement omits a condition - c

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].

Related

Why is my code inserting a new line when not requested?

I am running a simple decryption function and printing the plain text onto a file. The problem is that right at the previous-to-last line, the code inserts a new line that is nonexistent in the original encrypted file.
Note this is an exercise and it's a requirement for my task that I don't use any library header other than <stdio.h>, <stdlib.h>, <stdbool.h>.
This is the part of the code in question. I am using the for loops to wipe both arrays.
printf("Introdueix el nom de l'arxiu el qual vols desencriptar. Es creara l'arxiu Text_desxifrat.txt amb el contingut desencriptat\n");
scanf("%s", n_arxiu);
fit_x = fopen(n_arxiu, "r");
fit = fopen("Text_desxifrat.txt", "w");
if (fit_x == NULL) printf("Error en obrir el fitxer\n");
else{
while (fgets(text_xifrat, MAX*2, fit_x) != NULL){
desxifrar_frase(text_xifrat, m_clau, text);
fprintf(fit, "%s\n", text);
for (i = 0; (text[i] > 64 && text[i] < 91) || (text[i] == 32) || (text[i] > 48 && text[i] < 58); i++) text[i] = '\0';
for (i = 0; (text_xifrat[i] > 64 && text_xifrat[i] < 91) || (text_xifrat[i] == 32) || (text_xifrat[i] > 48 && text_xifrat[i] < 58); i++) text_xifrat[i] = '\0';
}
fclose(fit_x);
fclose(fit);
This is the void function desxifrar_frase used in the code before.
void desxifrar_frase(char frase[], char matriu_x[][7], char frase_desxifrada[]){
int i = 0, comptador = 0, fila, col;
while (frase[i+1] > 64 && frase[i+1] < 91){
fila = trobar_element(frase[i], true, matriu_x);
col = trobar_element(frase[i+1], false, matriu_x);
frase_desxifrada[comptador] = matriu_x[fila][col];
comptador++;
i+=2;
}
}
The next is the function trobar_element, that searches for the unencrypted value having its coordinates. It returns the ascii value of a capital letter.
int trobar_element(char element, bool fila, char matriu_x[][7]){
bool trobat = false;
int i = 0, valor;
if (fila){
while (!trobat){
if (element == matriu_x[i][0]){
valor = i;
trobat = true;
}
i++;
}
}
else{
while (!trobat){
if (element == matriu_x[0][i]){
valor = i;
trobat = true;
}
i++;
}
}
return valor;
}
I have the original file with the following content:
Soneto a una nariz
Erase un hombre a una nariz pegado
erase una nariz superlativa
erase una nariz sayon y escriba
era Ovidio Nason mas naridado
muchisima nariz tan fiera
que en la cara de Anas fuera delito
Quevedo
And this is the content of the file when ran through the code:
Soneto a una nariz
Erase un hombre a una nariz pegado
erase una nariz superlativa
erase una nariz sayon y escriba
era Ovidio Nason mas naridado
muchisima nariz tan fiera
que en la cara de Anas fuera delito
Quevedo
I have tried removing the \n in
fprintf(fit, "%s\n", text);
but it will return every line of the original file crammed together except for the last line (Quevedo), which will be the only word in the next line.

`else if` condition not properly working in my program in c

I am new and I don't know to to resolve this error.
When I give inputs for the third else if statement condition it gives the output as salary =0.
Can anyone explain why this happening?
I want to get the answer as :the salary of the candidate = 7000
but the output shows as : the salary of the candidate = 0
/******************* calculating the salary *********************/
/***** bitwise operator ***********/
#include <stdio.h>
int main()
{
char gen;
int qual, y_o_s, sal = 0 ;
printf ( "Enter Gender, Years of Service and Qualifications ( 0 = G, 1 = PG ):\n" );
printf("enter the gen, y_o_s, qual, \n");
scanf("%c\n%d\n%d", &gen, &y_o_s, &qual);
if (gen == 'M' && y_o_s >= 10 && qual == 1)
sal = 15000;
else if ((gen == 'M' && y_o_s >= 10 && qual == 0) ||
(gen = 'M' && y_o_s < 10 && qual == 1))
sal = 10000;
else if (gen == 'M' && y_o_s < 10 && qual == 0)
sal = 7000;
else if (gen == 'F' && y_o_s >= 10 && qual == 1)
sal= 12000;
else if (gen == 'F' && y_o_s >= 10 && qual == 0)
sal = 9000;
else if (gen == 'F' && y_o_s < 10 && qual == 1)
sal = 10000;
else if (gen == 'F' && y_o_s >= 10 && qual == 0)
sal = 6000;
printf("the salary of the candidat = %d\n", sal);
return 0;
}
I want to get the answer as :the salary of the candidate = 7000
but the output shows as : the salary of the candidate = 0.
Alter your if-else-if ladder like :
#define POST_GRAD 1
#define SEX_MALE 'M'
if (SEX_MALE == gen) {
if (POST_GRAD == qual) {
sal = (y_o_s >= 10) ? 15000 : 10000;
} else { // undergrad
sal = (y_o_s >= 10) ? 10000 : 7000;
}
} else { // not Male
if (POST_GRAD == qual) {
sal = (y_o_s >= 10) ? 12000 : 10000;
} else { // undergrad
sal = (y_o_s >= 10) ? 9000 : 6000;
}
}
It's easier to follow. Notice, that constants like POST_GRAD are on the left side comparator ==, it helps compiler catch unintended typos like = for comparisons.
Also, you may want those salaries at one place like :
#define MALE_PG_EXP_SAL 15000
#define MALE_UG_EXP_SAL 10000
// and so on
#define FEMALE_UG_EXP_SAL 9000
#define FEMALE_UG_INEXP_SAL 6000
When they change, you can find them at one place to modify.
PS: I wouldn't want to work at this place.
You are assigning a value to gen
else if ((gen == 'M' && y_o_s >= 10 && qual == 0) ||
(gen = 'M' && y_o_s < 10 && qual == 1))
^
So when you get to your next line gen is no longer what you expect.
else if (gen == 'M' && y_o_s < 10 && qual == 0)
^^
And then improve the code with SparKots suggestions.

Edit distance in C function called in Python does not return the correct result

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')

online compiler(online gdb)works correctly while g++ and gcc on windows 10 cmd doesn't work when comparing strings

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

Realloc crash my programa

Where problem ??, i trying do it with much forms but with realloc giveme errors.
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define numbs 10
//math.h para pow();
int main(){
int *array = malloc(numbs * sizeof(int));
if (array == NULL){
printf("Error in memory 1");
return -1;
}
int numbschanger = NULL;
int guardarcounter = NULL;
int *changedirinmemory = NULL;
int counter = NULL; // 0
int saveint = NULL;
int integer;
int numero = NULL;
int res = pow(2,3); // 2 ** 3 = 8, Una potencia.
printf("%d\n",res);
scanf("%d",&numero); // Guardar en la direccion numero.
fflush(stdin);
printf("Los divisores de %d son:\n",numero);
for(integer = 1;integer <= numero;integer++){
if (numero % integer == 0){ // Integer 1 porque si hacemos una divicion de numero / 0 Nos dara o un aviso en la consola de que no se puede dividir entre zero o un crash en el .exe
array[counter] = integer;
printf("%d\n",array[counter]);
counter++;
}
if (counter > numbs){
break;
}
}
printf("Haven\'t problem 01\n");
guardarcounter = counter;
saveint = integer; //Guardada el numero del integer, para que en el nuevo espacio de memoria pueda seguir comprobando "if (numero % integer == 0)"
for(integer;integer <= numero;integer++){
if (numero % integer == 0){
counter++;
}
}
if (numbs < counter){
printf("Campo del crash.");
numbschanger = numbs + counter;
changedirinmemory = realloc(array,numbschanger * sizeof(int)); //Crash hereeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
if (changedirinmemory == NULL){
printf("Error in memory 2");
return -1;
}
}
printf("Haven\'t problem 02\n");
for(saveint;saveint <= numero;saveint++){
if (numero % saveint == 0){
changedirinmemory[guardarcounter] = saveint;
printf("%d\n",changedirinmemory[guardarcounter]);
guardarcounter++;
}
}
printf("Haven\'t problem 03\n");
if (changedirinmemory != NULL){
free(changedirinmemory);
printf("\n\nEl nuevo espacio de memoria esta libre.");
}
else{
free(array);
printf("\n\nArray Libre.");
}
return 0;
}
If Weather Vane does not want to…
You problem lies in line 31 if (counter > numbs). That is not enough if counter is equal to numbs
With input 6125346 -> crash
Change line 31 to if (counter >= numbs)
Again with input 6125346 -> works perfectly
But you have a lot of small things in your code that are not fully correct. Please see the comments you got. You can also go to code review for further enlightenment but your code needs to work in the first place, otherwise they'll tear you into fine shreds.

Resources