1

Is it possible to stop scanning from file in the middle of the file? For example if I want to change this code to for loop with size/2.

edit: Can you please help me understand why i != toScan size(secondSize)?

fseek(toScan, 0, SEEK_END);
secondSize = ftell(toScan);
rewind(toScan);

fseek(toScan, 0.5 * secondSize, SEEK_SET);

while (fgetc(toScan) != EOF){
        rewind(signature);
        fseek(toScan, -1, SEEK_CUR);
        if (fgetc(toScan) == fgetc(signature)){
            fseek(toScan, -1, SEEK_CUR);
            temp = ftell(toScan);
            elements = fread(secondBuffer, 1, size, toScan);
            fseek(toScan, temp + 1, SEEK_SET);

            if (strcmp(secondBuffer, buffer) == 0){
                toReturn = 3; 
                break;
            }
        }

        rewind(signature);
        strncpy(secondBuffer, "", sizeof(secondBuffer));
        i++;
    }
Saga
  • 67
  • 1
  • 8
  • 3
    Certainly there is a *condition* that you're hedging will stop your scanning. *Right* ? Meeting that condition would certainly be cause to break your loop. So what problem are you *really* trying to solve? That belongs in your question. The posted code discards data from your file and is pretty much otherwise-pointless. – WhozCraig May 18 '17 at 18:29
  • Sure. Simply stop reading from the file. If you really want it to be the middle, figure out how big it is first and read half that many bytes. – David Hoelzer May 18 '17 at 18:33
  • When you say "middle", are you talking about exact "middle" position of a file? – Nguai al May 18 '17 at 18:33

1 Answers1

2

Yes, you can get the file size and then, in a loop:

for (i = 0; i < file_size / 2; i++) {
    int c = fgetc(file);
    ...
}

An example:

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

int main(void)
{
    FILE *file;
    long size, i;
    int c;

    file = fopen("demo.c", "rb");
    if (file == NULL) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }
    if (fseek(file, 0, SEEK_END) == -1) {
        perror("fseek");
        exit(EXIT_FAILURE);
    }
    size = ftell(file);
    if (size == -1) {
        perror("ftell");
        exit(EXIT_FAILURE);
    }
    if (fseek(file, 0, SEEK_SET) == -1) {
        perror("fseek");
        exit(EXIT_FAILURE);
    }
    for (i = 0; i < size / 2; i++) {
        c = fgetc(file);
        putchar(c);
    }
    fclose(file);
    return 0;
}
Community
  • 1
  • 1
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
  • 2
    @DavidHoelzer I am using `size /= 2;` ;) – David Ranieri May 18 '17 at 18:34
  • Using `fseek(..., SEEK_END )` to get to the end of a binary file is explicitly undefined behavior [per the C Standard](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf): "**7.21.9.2 The `fseek` function** ... A binary stream need not meaningfully support `fseek` calls with a `whence` value of `SEEK_END`." and footnote 268: "Setting the file position indicator to end-of-file, as with `fseek(file, 0, SEEK_END)`, has undefined behavior for a binary stream..." . – Andrew Henle May 18 '17 at 20:10
  • @AndrewHenle wow, I didn't know that, is there a cross-plattform alternative? – David Ranieri May 18 '17 at 20:13
  • @KeineLust Can you please help me? Look at the edit, can you help me to change this code to for loop instead of while? – Saga May 18 '17 at 21:41
  • 1
    @KeineLust As far as I know, there's no strictly-conforming portable way to easily get the size of a file in C. The only strictly-conforming, portable way I know to get the size of a file is read the entire file and count the bytes. – Andrew Henle May 19 '17 at 09:56
  • @Saga why are you rewinding again and again in your loop on each iteration? – David Ranieri May 19 '17 at 18:20
  • @Saga I don't know what you are trying to do, I've edited my code, this code does what you are asking in the title, read (and echoes) half file. – David Ranieri May 19 '17 at 18:27
  • @KeineLust Did you mean to rewind(signature)? – Saga May 19 '17 at 19:13
  • I mean you are using `rewind(signature);` (2 times) on each iteration , why? – David Ranieri May 19 '17 at 19:14
  • @KeineLust Oh ok you right. But I still can't understand why i != secondSize? And how can I change this. What I'm actually trying to do right now is to change my while loop to for loop(using i++ and i < secondSize instead of fgetc(toScan) != EOF). – Saga May 19 '17 at 22:07