0

So I'm scanning strings from a file and comparing them with the string from a stack. If i scan all the string from the file and don't find the one from the stack i want to rewind the file, pop the string from the stack and continue unless the stack is empty.

char buffer[ENOUGH];
while(fscanf(stream, "%s", buffer) != EOF)
{
    if(strcmp(buffer, tos->string) == 0)
    {
        pop(&tos);
        //do something with the string
    }
    // here i would need something to stop the EOF
}

I have a file like this:

02.01.2021 8:45 8:57 9:45
03.01.2021 15:40 16:30
05.01.2021 07:30 08:30

And stack contains:

01.01.2021 <- TOS
02.01.2021
03.01.2021
04.01.2021

So i need to find 01.01.2021 in file and if not there remove it from stack.

  • 1
    `fseek(stream, SEEK_SET, 0L)`? – iBug Jan 15 '21 at 08:29
  • @iBug Tried it but when i get to EOF it just doesn't want to set me back. –  Jan 15 '21 at 08:30
  • 1
    You need to rewrite some logic - when you hit the EOF you're already out of your `while` loop. – iBug Jan 15 '21 at 08:31
  • @iBug Any suggestions on how I could make it possible ? –  Jan 15 '21 at 08:32
  • 2
    Put this code inside another `while (stack not empty)` loop. – Barmar Jan 15 '21 at 08:35
  • Not a duplicate but probably enlightening: https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong – Yunnosch Jan 15 '21 at 09:28
  • Having a stack here rather than a list (double or single linked) is wrong in the first place. Can you replace the stack with a list? – Jabberwocky Jan 15 '21 at 09:30
  • @Jabberwocky Yeah of course but that doesn't change much, and for the main reason what the program should do is: Observe the stack/list, whatever you want, its like a period of time from 01.01.2021 to 04.01.2021 i need to print all the values of time on stdin from that stack/list if it isn't there there should print out the date and something like "No time data" –  Jan 15 '21 at 09:33
  • @Jabberwocky I thought about reading all the values from the file and making an array of linked lists from it and then compare it with the values from the stack, but I want to see if i can somehow do it this way. –  Jan 15 '21 at 09:36
  • It changes a lot. With a list you read the file only once. Roughly you read a line, if the line exists in the list you remove it from the list. Repeat this until the end of the file. – Jabberwocky Jan 15 '21 at 09:36

3 Answers3

1

To avoid reading the stream till the end of file, just break from the loop. Also note that you should compare the return value of fscanf() to 1 to detect all cases of failure. fscanf() will not return 0 for the %s or %c conversions, but would do so for other specifiers in case of a match failure that does not happen at end of file. Also pass a maximum number of characters to avoid undefined behavior on long input strings.

    char buffer[100];
    while (fscanf(stream, "%99s", buffer) == 1) {
        if (strcmp(buffer, tos->string) == 0) {
            pop(&tos);
            //do something with the string
            break;   // break from the loop.
        }
    }
    rewind(stream);
chqrlie
  • 131,814
  • 10
  • 121
  • 189
0

Probably something like this:

while (1)
{
  if (fscanf(stream, "%s", buffer) != EOF)
  {
    if (strcmp(buffer, tos->string) == 0)
    {
      if (stack is empty)
        break;

      pop(&tos);
      //do something with the string
    }
  }
  else
  {
    fseek(stream, 0, SEEK_SET);
  }
}

This is untested code, but you should get the idea.

But there is something flawed in your algorithm anyway: what happens if strcmp(buffer, tos->string) is never true?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • Yeah it is flawed don't know how to get around it, and for the question what happens if it is never true i wanted it to get to the EOF and with a checker to rewind the file stream, but don't know if it is possible. –  Jan 15 '21 at 09:03
0

You can use a method,

#include <stdio.h>

void compare(){
    char buffer[ENOUGH];

    while(fscanf(stream, "%s", buffer) != EOF){
        if(strcmp(buffer, tos->string) == 0){
            //do something
        }
    }
}

int main(void) {
    while(!stactIsEmpty()){
        pop();
        compare();
    }
    return 0;
}

This code is not tested. I hope you'll get the idea.

XO56
  • 332
  • 1
  • 12