2

I am reading the key and value for every pair in the list, ignoring the whitespaces and trying to print it. My file consists of data like:

(2, 50) (4, 30) (9, 30) (10, 400) (-5, -40)
(7, 20) (19, 200) (20, 50) (-18, -200) (-2, 29)
(2, 67) (4, 35) (9, 45) (-18, 100) 

I am trying to get the integers inside the parenetheses one by one. For eg.

m=2
n=50
m=4
n=30

I've tried to read data from the file till the file ends. Scan and print the m and n values.

    int m,n;
    FILE* file = fopen("File1.txt", "r"); // open a file
    while (!feof (file))
    {
        fscanf (file, "(%d, %d)", &m, &n);
        printf("m is %d:", m);
        printf("n is %d:", n);
    }
    //close the file after opening
    fclose (file);

The build is successful while running the code whereas

m is 2:n is 50:m is 2:n is 50:m is 2:n is 50:m is 2:n is 50:m is 2:n is 50:m is 2:n is 50:m is 2:

is printing endlessly instead of reading the integers from the file.

Kindly help.

Akhil Jain
  • 71
  • 1
  • 11

2 Answers2

3

Faults I see: first is the misuse of feof, the second is that the input is stuck at the second '(', where there is actually a space in the input data. You can filter out the (white) space by adding a space to the format specifer. Also you should always check if a file opened.

#include <stdio.h>

int main()
{
    int m,n;
    FILE* file = fopen("File1.txt", "r");
    if(file == NULL) {
        return 1;                                   // error checking
    }
    while (fscanf (file, " (%d,%d)", &m, &n) == 2)  // check for number of conversions
    //   space added here ^    ^ the space here was unnecessary
    {
        printf("m=%d, n=%d\n", m, n);
    }
    fclose(file);
    return 0;
}

Program output:

m=2, n=50
m=4, n=30
m=9, n=30
m=10, n=400
m=-5, n=-40
m=7, n=20
m=19, n=200
m=20, n=50
m=-18, n=-200
m=-2, n=29
m=2, n=67
m=4, n=35
m=9, n=45
m=-18, n=100

Because feof detects if there was a previous attempt to read beyond the end of the file, which you don't do, the end condition was never met.


Edit: answering the comment below, the format string can be made to tolerate additional whitespace anywhere in the input, by adding a space before every specifier that does not automatically filter whitespace. Like this:
fscanf (file, " (%d ,%d )", &m, &n)

There is now a space, in the format string, in front of each parenthesis and the comma. There doesn't need to be a space before each %d because that format spec automatically filters out leading whitespace. This will work correctly for randomly spaced input such as

"   (    4  ,  30  )  "
Weather Vane
  • 33,872
  • 7
  • 36
  • 56
0

Add space also in loop

int m,n;
FILE* file = fopen("file1.txt", "r"); // open a file
while(fscanf (file, "(%d, %d)", &m, &n)==2 || fscanf (file, "(%d, %d) ", &m, &n)==2 ||fscanf (file, " (%d, %d)", &m, &n)==2)
{
    printf("m is %d:\n", m);
    printf("n is %d:\n", n);
}
//close the file after opening
fclose (file);

Alternatively

int m,n;
char ch;
FILE* file = fopen("file1.txt", "r"); // open a file
while (!feof (file))
{
     fscanf (file, "(%d, %d)", &m, &n);
     printf("m is %d:\n", m);
     printf("n is %d:\n\n", n);
     while((ch = fgetc(file)) != EOF)
         if(ch == ' ')
             break;
}
//close the file after opening
fclose (file);

EDIT: To answer the comment.

EDIT2: Modified the regular expression to avoid space and line end

%*c this escape sequence can be added to avoid multiple characters. This is similar to using regular expression during scanf.

while(fscanf (file, "(%d%*c%d%*[) \n]", &m, &n)==2)
{
    printf("m is %d:\n", m);
    printf("n is %d:\n", n);
}
DTdev
  • 538
  • 1
  • 18
  • 32