1
for (int i = 0; i < num - 1 - ct; i++) {
    int tmp = k;
    fread(&k, sizeof(int), 1, fp);
    fflush(stdin);
    fseek(fp, -(sizeof(int)), SEEK_CUR);
    fwrite(&tmp, sizeof(int), 1, fp);
}

The question part is above. I want fseek to roll back 4 bytes every time. But it rolls back 8 bytes or maybe roll back to the beginning of the file. I can't make it work right. A freshman. Thanks in advance.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Yanel
  • 79
  • 3
  • 4
    Belaying the pointlessness and undefined-behavior nature of fflush of `stdin`, have you actually verified *any* of your IO calls by checking their result codes? They're not just there for convenience; they're there to help you trace down potential problems. – WhozCraig Jun 21 '21 at 04:46
  • 1
    [`fflush(stdin)` invokes UB](https://stackoverflow.com/q/2979209/995714) – phuclv Jun 21 '21 at 04:57
  • 3
    You don't show where `k` is defined or how it is initialized before the loop. How have you determined that `fseek()` reverses by 8 bytes instead of 4? Have you checked that `fp` is valid? How is it opened? Did you use `"rb+"` mode? However, the major problem may be the absence of an `fseek()` between the `fwrite()` at the end of one iteration of the loop and the `fread()` at the beginning of the next. You have to do an `fseek()` when switching from reading to writing (and you do) and also when switching from writing to reading (which you don't do). That leads to undefined behaviour, UB. – Jonathan Leffler Jun 21 '21 at 04:59
  • You `fflush(stdin)` and read/seek/write `fp`. Is it what you want? – fpiette Jun 21 '21 at 05:08
  • the expression: `sizeof( int )` will return 8 if the underlying hardware is 64 bit, the same as it returns 4 if the underlying hardware is 32 bit – user3629249 Jun 22 '21 at 15:55

2 Answers2

4

The problem is you do not use fseek() to sync the stream's internal data when switching from writing to reading from the same stream.

Try this:

fseek(fp, 0, SEEK_CUR);
for (int i = 0; i < num - 1 - ct; i++) {
    int tmp = k;
    fread(&k, sizeof(int), 1, fp);
    //fflush(stdin);  // this has undefined behavior
    fseek(fp, -(sizeof(int)), SEEK_CUR);
    fwrite(&tmp, sizeof(int), 1, fp);
    fseek(fp, 0, SEEK_CUR);
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
2

Try saving current position before reading and the use that position to move the file pointer. Be sure to open the file is "r+b" mode.

fp = fopen("Your file name", "r+b");
....
for (int i = 0; i < num - 1 - ct; i++){
    int tmp = k;
    long pos = ftell(fp);
    fread(&k, sizeof(int), 1, fp);
    fflush(stdin);   // What has stdin to do here while your read/seek/write fp
    fseek(fp, pos - sizeof(int), SEEK_SET);
    fwrite(&tmp, sizeof(int), 1, fp);
}

And don't forget to add checking the return value of any of the function used.

fpiette
  • 11,983
  • 1
  • 24
  • 46
  • Or use [`fgetpos`](https://en.cppreference.com/w/c/io/fgetpos) and [`fsetpos`](https://en.cppreference.com/w/c/io/fsetpos) – WhozCraig Jun 21 '21 at 05:14