0

I have a very large program right now that I'm fairly certain that I should not publish publicly without getting into a lot of trouble so I'm going to try my best to explain the issue at hand.

I have 3 different functions, the names are different but the pointer names in the function match exactly, I'm not allowed to change the pointer names:

int function_1 (FILE \*in, FILE \* out, FILE \*changes);

int function_2(TYPEDEF STRUCT \*s, FILE \*in);

int function_3(TYPEDEF STRUCT \*s, FILE \*in);

My main function calls function_1 using function_1(stdin, stdout, changes) where changes is a pointer to a file stream that was opened in main.

In function1, I call function2(s,changes) and function_3(s,changes) in a loop. I also use fgetc(in) in function_1 after calling 2 and 3. I am failing in the first loop because I have a mismatch comparing characters between changes and stdin, when the are supposed to be the same.

For some strange reason, I find that by the time I get to the line int a=fgetc(in) in function_1, the stdin FILE stream has already lost two characters. If I add a line to fgetc(in) prior to calling function_2*,* I get the first letter in stdin and then my original int a=fgetc(in) shifts down one letter. Using this method, I determined that a character from stdin is lost after a call to function2 and another character from stdin is lost after function_3. However, I did not pass the *in pointer into those functions, I passed the *changes pointer.

I have never been more confused as to why this is happening, it doesn't make sense. If there was a problem with the fgetc(in) calls in the other two functions, it shouldn't only take off two characters as there are many of them in the other two functions, and those fgetc(in) calls are pulling the characters from the changes stream correctly.

Has anyone run into this before? Thanks in advance for any guidance.

edit: I think this is as minimal of an example that I can get. I also just discovered that if I comment out the EOF If statement checks, I no longer lose the two characters.

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

int next_struct(MYSTRUCT *s, FILE *in) {
    int current_c = fgetc(in);
    int eof_check= current_c;

    if ((eof_check = getchar()) != EOF) {
        //do stuff here
    }
    else {
        return EOF;
    }

    //do more stuff

    return 0;
}

int get_struct_c(MYSTRUCT *s, FILE *in) {
    int c = fgetc(in);
    int eof_check2= c;
    if ((eof_check2=getchar()) != EOF) {

        //do stuff
    }
    else {
        return EOF;
    }

    return character;
}

int patch(FILE *in, FILE *out, FILE *diff) {
    //intialize typedef struct
    //create pointer to struct

    while (!feof(diff)) {
        if (next_struct(s,diff) == 0) {

        //get charaters from diff and add to output
        hunk_c = get_struct_c(s,diff);

        read_c = fgetc(in);
        fprintf(stderr, "%c\n", read_c);
    }

    return 0;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • I think you're going to have to give us a [mcve]. It need not be your entire secret code base, or even any part of it. Strip it down to the minimum that reproduces the bug. Then, if that's still too secret, write a new program that does the same thing. – Nate Eldredge Feb 19 '23 at 06:29
  • The only thing I can think of offhand is that on some systems (mainly Windows), line breaks are CRLF, but in text mode (i.e. if not including `b` in the fopen mode), they have to read as a single `\n` character. So if you read one character but it's a CR, then the following LF will be consumed as well. That doesn't sound very much like what you describe, though. – Nate Eldredge Feb 19 '23 at 06:31
  • I added a minimal reproducible example to my post. I'm also running this on a linux vm, so CRLF is not applicable here. – eternallymisty Feb 19 '23 at 06:52
  • 2
    `getchar();` is, effectively `fgetc( stdin );` Perhaps you want only `if( current_c != EOF )`? The first character taken from the stream is disregarded and overwritten. – Fe2O3 Feb 19 '23 at 06:56
  • It is not reproducible until it reproduces. This means compiles, runs, and shows the same error your real program does. – n. m. could be an AI Feb 19 '23 at 06:58
  • ```int current_c = fgetc(in); int eof_check= current_c; if ((eof_check = getchar()) != EOF) {``` ---> This doesn't make sense. – Harith Feb 19 '23 at 06:58
  • that worked changing it to currect_c != EOF. Thank you. – eternallymisty Feb 19 '23 at 07:01
  • 1
    eternallymisty, `while (!feof(diff)) {` --> [Why is “while( !feof(file) )” always wrong?](https://stackoverflow.com/q/5431941/2410359). – chux - Reinstate Monica Feb 19 '23 at 07:20
  • @eternallymisty Where is `}` for `if (next_struct(s,diff) == 0) {`? Best to post a [mcve]. – chux - Reinstate Monica Feb 19 '23 at 07:22

0 Answers0