1

I am reading a file named "text.txt" that contains a series of numbers with a space in between. I want to write in a new file named "text_nr.txt", all the numbers in "text.txt" but without repetition! My code runs in an infinite loop at the second while loop, but I can't understand why.

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


int main()
{
    int n=0,m=0,nr;

    FILE *fp1;
    FILE *fp2;
    fp1 = fopen("text.txt","r");
    fp2 = fopen("text_nr.txt","a+");

    while(fscanf(fp1,"%d",&n) != EOF){
        nr=0;
        while(fscanf(fp2,"%d",&m) != EOF){
            printf("%d  %d ",m,n);
            if(n != m) continue;
            else{
                nr++;
                break;
            }
        }   
        if(nr == 0){
            fprintf(fp2,"%d ",n);
        }
    }

    fclose(fp1);
    fclose(fp2);

    return 0;      
}
10
  • 1
    At some point in the input, the format to fscanf doesn't match, so fscanf returns 0 but does not advance the file pointer. So it keeps reading from the same spot and returns 0 each time. Commented May 29, 2016 at 12:14
  • 3
    Consider using a debugger. It's fun! :-) Commented May 29, 2016 at 12:14
  • @WilliamPursell It does that at first time it starts to run. I have just started working with files and i don't know why that happens. Can you explain a bit further so i can understand and fix this problem ? Commented May 29, 2016 at 12:17
  • 1
    My general approach to these types of problems is to never use scanf, so I'm not the one to help! IMO, scanf is complicated, and you will learn more if you use fread and strtol instead. Commented May 29, 2016 at 12:19
  • @WilliamPursell Thanks, I will try another approach! Commented May 29, 2016 at 12:20

3 Answers 3

1

Functions like fscanf() return various values like EOF (end of file or error ) or the number of specifiers matched, 0, 1, ...

Rather than test for one value code needs to stop on, test against all undesired values.

// while(fscanf(fp1,"%d",&n) != EOF){
while(fscanf(fp1,"%d",&n) == 1){
    nr=0;
    // while(fscanf(fp2,"%d",&m) != EOF){
    while(fscanf(fp2,"%d",&m) == 1){

@William Pursell explained it well

At some point in the input, the format to fscanf doesn't match, so fscanf returns 0 but does not advance the file pointer. So it keeps reading from the same spot and returns 0 each time.

Infinite loop.

Sign up to request clarification or add additional context in comments.

1 Comment

Creative license with 'line' -> 'like' in first line :)
1

Your inner loop will not reach the end of file since it won't match your search string if the file starts empty.

You could do the fscanf and check if it's 0 (couldn't find anything) or EOF (hit the end).

4 Comments

Doesn't it hit EOF at the first time it starts to read it if the file is empty?
Even if your at the start of an empty file, you've not hit the EOF flag, so no. (Updated the answer for clarity)
Even if the second file is not empty it still runs in an infinite loop. Itried to put some numbers in there
Wha do you get if you change "!= EOF" to "== 1" ?
0

Try to use fseek function to move stream pointer inside output file.

 while(fscanf(fp1,"%d",&n) != EOF){

    fseek ( fp2, 0 , SEEK_SET );
    bool flag = false;

    while(fscanf_s(fp2,"%d",&m) != EOF){
        printf("%d  %d ",m,n);

        if(n == m) 
        {
            printf("%d = %d ", m, n);
            flag = true;


            break;
        }
    }   
    if(!flag)
    {
        fseek ( fp2, 0 , SEEK_END );
        fprintf(fp2,"%d ",n);
    }
}

EDIT

Another method is to store written values in array. For this you can use vector.

vector<int> vData;

while(fscanf(fp1,"%d",&n) != EOF){


    bool flag = false;

    for(int i = 0; i < vData.size(); i++)
    {
        if(vData[i] == n)
        {
            flag = true;
            break;
        }
    }

    if(!flag)
    {
        vData.push(n);
        fprintf(fp2,"%d ",n);
    }
}

3 Comments

It still runs in an infinite loop!
I've made some changes. What numbers are you comparing?
This doesn't chane anything, the program fails here: while(fscanf(fp2,"%d",&m) != EOF){ printf("%d %d ",m,n);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.