1

I have this little program which reads a long text document from allomany.txt.It contains a long text where we have some numbers.Now I need to falsify every number: Let is assume the program needs to read the text from file and I need to find a number(the number is string).Then I need to check if the string is a number. If yes then I need to falsify it by using bitwise operations.

Falsification: if I find a number in string(atoi, sscanf) then I need to increment the number which is found in the string. Example: if the program finds 14 we increase it 15 using bitwise operations. I found an example for this on the net if I remember correctly: (-(~n)). If I don't use bitwise operations it works.

The question: how to do this with bitwise operations ?

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

int main()
{
    FILE *fin,*fout;
    char *token, s[1000];

    fin = fopen("allomany.txt","rt");
    fout = fopen("hamisitott.txt","wt");

    while (fscanf(fin, "%[^\n]\n", s) != EOF) {
        token = strtok(s, " ");
        while (token != NULL) {
            if (atof(token) > 0)
                fprintf(fout, "%g ", atof(token) + 1);
            else fprintf(fout, "%s ", token);
            token = strtok(NULL, " ");
        }
        fprintf(fout, "\n");
    }

    fclose(fin);
    fclose(fout);

    return EXIT_SUCCESS;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
Zsombi
  • 84
  • 1
  • 9

1 Answers1

2

Incrementing the numbers with bitwise operations seems a bit complicated, I suggest a simple alternative: change every digit in the file from even to odd and vice versa by flipping the low order bit:

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

int main(void) {
    FILE *fin = fopen("allomany.txt", "r");
    FILE *fout = fopen("hamisitott.txt", "w");
    int c;

    if (fin == NULL || fout == NULL) {
        fprintf(stderr, "cannot open files\n");
        exit(EXIT_FAILURE);
    }
    while ((c = getc(fin)) != EOF) {
        if (c >= '0' && c <= '9')
            c = '0' + ((c - '0') ^ 1);
        putc(c, fout);
    }
    fclose(fin);
    fclose(fout);

    return EXIT_SUCCESS;
}

You could also implement other permutations of digits with a different expression (but without bitwise operations):

c = "9876543210"[c - '0'];

EDIT I changed c ^= 1 into c = '0' + ((c - '0') ^ 1) to avoid assuming that '0' be even. The C Standard only guarantees that digits '0' through '9' are adjacent and strictly positive.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • `c ^= 1;` works if `'0'` is even, which is a reasonable assumption. `c = "9876543210"[c - '0'];` better but is not " falsificate it by using bitwise operations". – chux - Reinstate Monica Mar 08 '16 at 21:34
  • 1
    Perhaps `c = (c - '0')^1 + '0'` or some variation? – chux - Reinstate Monica Mar 08 '16 at 21:37
  • it is works but let's assume i have number 2016. Your program will increment them to 3127. I only need to increment it to 2017 – Zsombi Mar 08 '16 at 22:04
  • @chux: good point! some variation indeed, because of operator precedence. – chqrlie Mar 08 '16 at 22:22
  • @Zsombi: incrementing just by one is far more complicated with just bitwise operations, note that `3127` would be changed to `2016`. The operation would be idempotent, applying it twice undoes the falsification, quite handy. – chqrlie Mar 08 '16 at 22:24
  • @Zsombi What is wrong with `3127`? "I need to falsificate every number" --> `3127` looks like a changed number to me. _Must_ the number be incremented? What if the number is 1234567890123456789012345678901234567890 or some thousand digit long number? – chux - Reinstate Monica Mar 08 '16 at 22:25
  • If we are going for *bitwise* operations, why not `((c - '0') ^ 1) | '0';`? – David C. Rankin Mar 08 '16 at 23:20
  • @DavidC.Rankin: I used to have `c ^= 1`, but chux pointed out that I was assuming `'0'` to be even (which of course is true in ASCII and EBCDIC). Your expression makes an even stronger assumption, that `'0'` is a multiple of 16, which is also true in ASCII and EBCDIC, but is not guaranteed by the C Standard. – chqrlie Mar 09 '16 at 00:30