help with my code in C

I know, this page is about programing in c++ but c and c++ are little equal, and my question is simple,

I read 2 int, int x and int c, x is a value and c is the "caracther" but not is a char , in x I will find the c and delete, example:

25798 6

the hexadecimal value is 0x000064C6, and the
character in the input is 6. Through operators and use of masks, I should
eliminating overwrite the number 6 and typing 0 (zero ) instead .

The resulting number is hexadecimal 1216 is 0x000004C0 . You must write
in the output file the new number is 1216. No pass is asking
hexadecimal , only mentioned to illustrate the requirement.

but the code print 1246, no 1216 :( I don't know why .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

#include <stdio.h>
#include <stdlib.h>

void imprimir (int cadena, int auxiliar, int newcadena, int c){
	if(cadena==0){
		printf("%d" , auxiliar);
	}else{
		auxiliar =cadena & 0xf;
		if(auxiliar==c){
			newcadena=cadena ^ auxiliar;
			cadena=cadena>>4;
			//printf ("%d", 0);
			imprimir ( cadena, auxiliar, newcadena, c);
			}else{
				newcadena= cadena ^ auxiliar;
				cadena=cadena>>4;
				printf("%d", auxiliar);
				imprimir (cadena,auxiliar,newcadena,c);
				}
			
		}
}

int main(){
	int x;
	x= 25798; 
	int caracther =6;
	int aux=0;
	int newcad=0;
	
	imprimir( x, aux,newcad,caracther );
	return 0;
}
Last edited on
You do use recursion.

I would have converted (with snprintf) the decimal value to a string that shows the hexadecimal value. Then do a "replace_if" for characters in the string. Finally, sscanf back to integer.
Well, I prefer the nybble-wise approach to converting to a string and back.

But...

1. Your if(auxiliar==c){ condition is running the same code whether the condition evaluates to true or false (save for the commented out printf.) You should be throwing away the nybble when it matches, otherwise keeping it.

2. The way you are building the newcadena value doesn't look right. For example, you are not taking account of how cadena is being bit shifted.

3. Does auxiliar have to be passed to the function when you recurse??

Also, given you said you had to achieve your aim "Through operators and use of masks, ...", I can see a solution which does not shift cadena. But does use masking, which you are not yet doing.

Andy

PS printing out the hex value would help with debugging, though.
Last edited on
Hello I made the recursive program I thought that would be the correct way when printing numbers, the machine and makes all operations on binary hex conversion is necessary is just an example to guide us .

to answer andywestken , step "auxiliary" because that is the value of the number that was extracted with & 0xf , and so if it comes to my base case recursively see if the chain 0 then prints the axuxiliar and then print it from back to front ,I mean would print from left to right the number value with the value they tell me to remove

if you know another way to make this perfect code , for I find no other way and not showing me by 1246 and not 1216 , I am open to suggestions and advice thanks .
Last edited on
Tail recursion and a loop are close kin.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int foo( int cadena, int c ) {
    int HB = 16;
    int result = 0;
    int mult = 1;
    while ( 0 < cadena ) {
        int z = cadena % HB;
        result += mult * z;
        mult *= HB;
        printf( "%x %x\n", z, result );

        cadena /= HB;
    }
    return result;
}

The replacement I leave to you. I can see how value 0-9 work for caracther, but what about the a-f range?
oh i forgot something, the only operations that I can do are:

!
~
^
&
|
+
<<
>>

and, I make other code again, is more short but now printf other value.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        int x=25798,sum,carac=6,i=0; 
	int masca=0xff;
	int aux; 
	
	while(i<8){
		
		aux = x & masca;
		if(aux==carac){
			sum=sum+0;
			masca=masca<<4;	
			}else{
				sum=sum+aux;
			masca=masca<<4;	
		}
		i++;
	}
	
	printf("%d", sum);
	return 0;


is i<8 because this program is in machine in 32 bits
Last edited on
Notes:

* Line 9 does nothing, so should be removed.

* Lines 10 and 13 are unnecessary repetition. Do that shift only once, outside of the IF.

* Are the operators on lines 8 and 15 in the allowed list?

* What is the initial value of 'sum'?
sum=0 sorry, I forgot that,

masca= 0xf not 0xff

i is valid, i don't use is array

The last code you posted was almost there; you just needed to shift carac as well as the mask.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        int x=25798,sum=0,carac=6,i=0; // sum now init to 0
	int masca=0xf; // mask now 0xf rather than 0xff
	int aux; 

	while(i<8){

		aux = x & masca;
		if(aux==carac){
			//sum=sum+0;      // after keskiverto (does nothing)
			//masca=masca<<4; // after keskiverto (move out of if)
		}else{
			sum=sum+aux;
			//masca=masca<<4; // after keskiverto (move out of if)
		}
		carac=carac<<4; // ALSO SHIFT carac
		masca=masca<<4; // after keskiverto (moved here)
		i++;
	}

	printf("%d", sum);
	return 0;


OR, as a complete runnable program (in C++ Shell), with a bit more output

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdio.h>

int main(){
    int x=25798,sum=0,carac=6,i=0; // sum now init to 0
    int masca=0xf; // mask now 0xf rather than 0xff
    int aux=0;// for completeness

    printf("INPUT\n");
    printf("in dec : %d\n", x);
    printf("in hex : %x\n", x);
    printf("\n");

    printf("REMOVE all nybbles which are %x\n", carac);
    printf("\n");

    while(i<8){
        aux = x & masca;
        if(aux==carac){
            //sum=sum+0;      // after keskiverto (does nothing)
            //masca=masca<<4; // after keskiverto (move out of if)
        }else{
            sum=sum+aux;
            //masca=masca<<4; // after keskiverto (move out of if)
        }
        carac=carac<<4; // ALSO SHIFT carac
        masca=masca<<4; // after keskiverto (moved here)
        i++;
    }

    printf("OUTPUT\n");
    printf("in dec : %d\n", sum);
    printf("in hex : %x\n", sum);
    printf("\n");

    return 0;
}


INPUT
in dec : 25798
in hex : 64c6

REMOVE all nybbles which are 6

OUTPUT
in dec : 1216
in hex : 4c0


Andy
Last edited on
PS When working on algorithms, it can help to use a test harness which checks assorted value for you. Esp. useful when you're trying to improve a working function. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <stdio.h>

#define TAKE 5

// now a function
int stripNybble(int x, int carac) {
    int sum=0,i=0;// sum zeroed
    int masca=0xf;// was 0xff
    int aux=0;// for completeness
#if TAKE == 1
    while(i<8){
        aux = x & masca;
        if(aux==carac){
            sum=sum+0;
            masca=masca<<4;
        }else{
            sum=sum+aux;
            masca=masca<<4;
        }
        i++;
    }
#elif TAKE == 2
    while(i<8){
        aux = x & masca;
        if(aux==carac){
            //sum=sum+0;      // TAKE 2
            //masca=masca<<4; // TAKE 2
        }else{
            sum=sum+aux;
            //masca=masca<<4; // TAKE 2
        }
        masca=masca<<4; // TAKE 2
        i++;
    }
#elif TAKE == 3
    while(i<8){
        aux = x & masca;
        if(aux==carac){
            //sum=sum+0;      // TAKE 2
            //masca=masca<<4; // TAKE 2
        }else{
            sum=sum+aux;
            //masca=masca<<4; // TAKE 2
        }
        carac=carac<<4; // TAKE 3 - also shift carac
        masca=masca<<4; // TAKE 2
        i++;
    }
#elif TAKE == 4
    // exploit fact that if you shift a value left (or right) enough times
    // it eventually becomes 0 to eliminate the need for i
    while(0 != masca){
        aux = x & masca;
        if(aux != carac){
            sum=sum|aux; // and use bit-wise or rather than add
        }
        carac=carac<<4;
        masca=masca<<4;
    }
#elif TAKE == 5
    while(0 != masca){
        aux = x & masca;
        if(aux != carac){
            sum |= aux; // switch to short form of sum = sum | aux, etc
        }
        carac <<= 4;
        masca <<= 4;
    }
#endif
    return sum;
}

int main(){
    struct TestCase {
        int x;
        int carac;
        int expectedResult;
    };

    //easier to define test cases in hex
    TestCase testCases[] =
    { {0x64C6, 0x6, 0x04C0}
    , {0x1234, 0x1, 0x0234}
    , {0x1234, 0x4, 0x1230}
    , {0x3535, 0x3, 0x0505}
    , {0x3535, 0x5, 0x3030}
    , {0x6666, 0x6, 0x0000}
    , {0x6666, 0x2, 0x6666} };

    const int count = sizeof(testCases)/sizeof(testCases[0]);

    int passes = 0;

    for(int i = 0; i < count; ++i) {
        printf("INPUT\n");
        printf("in dec : %d\n", testCases[i].x);
        printf("in hex : %x\n", testCases[i].x);

        printf("REMOVE all nybbles which are %x\n", testCases[i].carac);
        int result = stripNybble(testCases[i].x, testCases[i].carac);

        printf("OUTPUT\n");
        printf("in dec : %d\n", result);
        printf("in hex : %x\n", result);
        if(result == testCases[i].expectedResult)
        {
            printf("pass!\n");
            ++passes;
        }
        else
        {
            printf("fail!\n");
        }
        printf("\n");
    }

    printf("RESULTS\n");
    printf("ran %d\n", count);
    printf("passed %d\n", passes);
    printf("failed %d\n", (count- passes));
    printf("\n");

    return 0;
}


Andy
Last edited on
the only operations that I can do are
! ~ ^ & | + << >>

That list does not contain == or ++. The "allowed" operations can replace them though.
Topic archived. No new replies allowed.