0

I am trying to compare letter by letter a text in a file with other text in another file. If there is a similarity, it prints a bit in a different file which is the "output" file.

In fact it only works for the first letter of the text.

Can someone explain to me?

Here's my program :

void write_from_file(){
    FILE*f1 = fopen("Test.txt","r");
    FILE*f2 = fopen("dictionnaire.txt","r");
    FILE*f3 = fopen("output.txt","a+");
    int c=0;
    do{
        c = fgetc(f1);
        do {
            char c2;
            int bi;
            fscanf(f2,"%c %d",&c2, &bi);
            printf("c = %c\n",c);
            printf("c2 = %c\n",c2);
            if(c==c2){ 
                printf("%d",bi);
            }
        }while(!feof(f2));
    }while(c != EOF);
}

here's the dictionary :

a 500000001 b 500000010 c 500100001 d 500000011 e 500000100 f 500000101 g 500000110 h 500000111 i 500001000 j 500001001 k 500001010 l 500001011 m 500001100 n 500001101 o 500001110 p 500001111 q 500010000 r 500010001 s 500010010 t 500010011 u 500010100 v 500010101 w 500010111 x 500011000 y 500011001 z 500011010 A 510000001 B 510000010 C 510000001 D 510000011 E 510000100 F 510000101 G 510000110 K 510000111 I 510001000 J 510001001 K 510001010 L 510001011 M 510001100 N 510001101 O 510001110 P 510001111
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • `c` is used without being initialized in the inner loop. It invokes *undefined behavior*. – MikeCAT Oct 29 '20 at 17:03
  • @MikeCAT `c2` I think you mean. – Zan Lynx Oct 29 '20 at 17:03
  • You need to check the value returned by `fscanf`. You also should never call `feof` until you've seen `fgetc` or `fscanf` return a value to indicate end of data. – William Pursell Oct 29 '20 at 17:04
  • Also you __must__ check if `fopen` succeeds. `fopen` is one of the functions that fail most, usually because the file it tries to open does not exist. – Jabberwocky Oct 29 '20 at 17:04
  • @ZanLynx No, I mean `c`. `c2` might be uninitialized, but some data may be read there via `fscanf()`. – MikeCAT Oct 29 '20 at 17:04
  • Why are you using a `do/while` loop instead of a `while` loop? It makes no sense to check `c` if you get EOF on the read from `f1`. – William Pursell Oct 29 '20 at 17:05
  • 3
    Your question title does not actually describe your question. Also, you did not include a complete program. Add the headers and main function. You should also include samples of Test.txt and dictionnaire.txt, just a few lines each. In other words, please include enough for someone else to reproduce it. – Zan Lynx Oct 29 '20 at 17:05
  • 1
    @MikeCAT maybe it was edited at some point but `c` is set to 0 when declared, and set by fgetc again at the top of the do loop. – Zan Lynx Oct 29 '20 at 17:07
  • 1
    thank you all of you ! here's the dictionnary : a 500000001 b 500000010 c 500100001 d 500000011 e 500000100 f 500000101 g 500000110 h 500000111 i 500001000 j 500001001 k 500001010 l 500001011 m 500001100 n 500001101 o 500001110 p 500001111 q 500010000 r 500010001 s 500010010 t 500010011 u 500010100 v 500010101 w 500010111 x 500011000 y 500011001 z 500011010 A 510000001 B 510000010 C 510000001 D 510000011 E 510000100 F 510000101 G 510000110 K 510000111 I 510001000 J 510001001 K 510001010 L 510001011 M 510001100 N 510001101 O 510001110 P 510001111 – pierreChemin Oct 29 '20 at 17:10
  • there isn't everything because it is too long (i know it is not very smart) – pierreChemin Oct 29 '20 at 17:10
  • in the file test, there is only : Alice – pierreChemin Oct 29 '20 at 17:10
  • @WilliamPursell you are suggesting to the OP that it is not safe to call feof() before an I/O function returns EOF. This is not true. – DarkAtom Oct 29 '20 at 17:11
  • 3
    @DarkAtom yeah `feof()` is safe, but meaningless. It only becomes true after a read operation has failed. – Zan Lynx Oct 29 '20 at 17:12
  • c = A c2 = ; c = A c2 = c = A c2 = ├ c = A c2 = á c = l c2 = á c = i c2 = á c = c c2 = á c = e c2 = á c = c2 = á – pierreChemin Oct 29 '20 at 17:12
  • an this is the end of the output – pierreChemin Oct 29 '20 at 17:12
  • This is not an answer because I am not sure it will help, but ... Check your functions for the correct return values. For example, check every `fopen` to see if it returned NULL. Check every `fscanf` to see if it returned 2 (the number of items it should have read). Check your `fgetc` for EOF. Which you do, but do the check right after instead of at the end of the loop. – Zan Lynx Oct 29 '20 at 17:16

2 Answers2

1

At least this problem: code is reading the prior line's '\n' into c2.

// fscanf(f2,"%c %d",&c2, &bi);
if (fscanf(f2," %c %d",&c2, &bi) != 2) break;
//             ^ add space to consume any white-space first. 

See also Why is “while ( !feof (file) )” always wrong?.


As well answered by @Zan Lynx, rewind() the dictionary, to search it again after getting a new letter from the user.


Advanced issue:

fgetc() returns an int value in the unsigned char range or EOF. Should the user enter a non-ASCII character, c will be a value in the [128-255] range. With char as a signed char, c==c2 will always fail. Better to use unsigned char c2.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
1

Here is how I would do it. I believe your biggest problems were the failure of your fscanf pattern. It needed a space after it in order to eat the space. Otherwise the %c would read the space. And you needed to rewind your dictionary file to start from the beginning again.

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

void fail(const char *msg) {
  perror(msg);
  exit(EXIT_FAILURE);
}

void write_from_file() {
  FILE *f1 = fopen("Test.txt", "r");
  if (!f1)
    fail("Test.txt");
  FILE *f2 = fopen("dictionnaire.txt", "r");
  if (!f2)
    fail("dictionnaire.txt");
  FILE *f3 = fopen("output.txt", "a+");
  if (!f3)
    fail("output.txt");

  int c = 0;
  while ((c = fgetc(f1)) != EOF) {
    char c2;
    int bi;
    while (fscanf(f2, "%c %d ", &c2, &bi) == 2) {
      // printf("c  = %c\n", c);
      // printf("c2 = %c\n", c2);
      if (c == c2) {
        printf("%d\n", bi);
        break;
      }
    }
    rewind(f2);
  }
}

int main() {
  write_from_file();
  return EXIT_SUCCESS;
}
Zan Lynx
  • 53,022
  • 10
  • 79
  • 131