I have a question:
I have a file named "data.inp". This file have numbers:
6 3 5 4 5
2 5 3 1
5 8 7 9
2 5 6 3 5 8 4 6
If I want more line of numbers, I will add numbers.
But I don't know how to read file "data.inp" line by line. I think I should use fgets, but seem that fgets is used for char. Or I used fgetc to read all numbers, then I count '\n' (note: "enter"), add 1, I have number of line. Then maybe I read file by that way?
thanks in advance!;)

Recommended Answers

All 17 Replies

fgets() doesn't know the difference between characters, such as 'a', 'b', 'c' ... and numbers such as '1', '2', '3' ... '9'. In the file they are all just text. If you want to treat all those numbers as text, read the file line by line, then just use fgets() the normal way

char line[80]
FILE* fp = fopen("data.inp","r");
while(fgets(line,1,sizeof(line),fp)
{
   // do something
}
fclose(fp);

If you just want to add more lines to that file, then it isn't necessary to read it at all. Open the file for append and start writing -- new lines will be appended to the end of the existing lines.

But I don't know how to read file "data.inp" line by line. I think I should use fgets, but seem that fgets is used for char.

Yes, use fgets() to read the line, then you can use sscanf() to convert the line into numbers.

If I caculate sum of numbers line by line.
This file "data.inp" have numbers:
6 3 5 4 5
2 5 3 1
5 8 7 9
2 5 6 3 5 8 4 6
I want the result is:
23
11
29
39
(Note: 29= 6 +3 +5 +4 +5
11= 2 +5+ 3+ 1
29= 5 +8 +7 +9
39= 2 +5 +6 +3 +5 +8+ 4+ 6)
thanks!

OK. So use the information from my post and think about how you'd have to do it.

Or read the link from Dave. Two possible ways to handle this.

I try but I can't run my program.
Have EOL (end of line) in C?
I know only EOF. I used fgets but it read for char

Post your code so that we can atleast point out the mistakes you are making...

Member Avatar for iamthwee

I try but I can't run my program.
Have EOL (end of line) in C?
I know only EOF. I used fgets but it read for char

Stay away from EOF, use the examples as shown.

Here is my code :

#include<conio.h>
#include<stdio.h>
main()
{
    clrscr();
    int v[10],v1[10],i=0,j,t,k,number,count=0;
    FILE *f ;
    f=fopen("numbers.inp","r");
/* open file numbers.inp to read, for e.g, you inputs two rows ( can be more than two ) of number 
    5 4 4 3 3 3 2
    2 2 1 
*/
     do
     {
        i++;
        fscanf(f,"%d",&v[i]);
        count++;
     }
/* after these above commands, I change all chars in numbers.inp to integers belong to array v[i] so I think 5 4 4 3 3 3 2 and 2 2 1 now are integer not char */
     while((number=getc(f))!=EOF);
/* I think problem is here, when I use fscanf I lost two rows and now
it read to end of file and it considers my two rows as one row v[i]={5 4 4 3 3 3 2 2 2 1} and it apply the beneath algorithm for it.
What I want is it does the algorithm to the first row 5 4 4 3 3 3 2 and export result to result.out, then does with the second row 2 2 1 and export result to result.out */
     k=count;
     while(v[1]>0)
     {
        for(i=2;i<=(v[1]+1);i++)
            v1[i-1]=v[i]-1;
        for(i=(v[1]+2);i<=count;i++)
            v1[i-1]=v[i];
        count--;
        for(i=1;i<=count;i++)
            v[i]=v1[i];
        for(i=1;i<=(count-1);i++)
        for(j=(i+1);j<=count;j++)
        if(v[i]<v[j])
        {
            t=v[i];
            v[i]=v[j];
            v[j]=t;
        }
        for(i=1;i<=count;i++)
        {
            printf("%2d",v[i]);
            if(i==count)     printf("\n");
        }
        k--;
     }
     f=fopen("result.out","w");
     i=k;
     if(v[i]>(k-1)||(v[i]<0)) fprintf(f,"NO");
     if(v[i]==0) fprintf(f,"YES");
     getch();
     fclose(f);
    }

Hope you understand me.

fscanf() does not differentiate between rows. So you will be better off not using that function at all. Instead, I would use fgets() to read one row at a time then parse the string that was read.

char line[80];
char *ptr = 0;
int i = 0;

while( fgets(line, sizeof(line), f) != NULL)
{
   // clear the array
   memset(v,0,sizeof(v));
   i = 0;
   // extract numbers from line string
   ptr = strtok(line," ");
   while( ptr != NULL)
   {
       // insert into array
       v[i] = atoi(ptr);
      ++i;
      // get next number from the string
      ptr = strtok(NULL, " ");
    }
    // now do something with these numbers

}

fscanf() does not differentiate between rows. So you will be better off not using that function at all. Instead, I would use fgets() to read one row at a time then parse the string that was read.

char line[80];
char *ptr = 0;
int i = 0;

while( fgets(line, sizeof(line), f) != NULL)
{
   // clear the array
   memset(v,0,sizeof(v));
   i = 0;
   // extract numbers from line string
   ptr = strtok(line," ");
   while( ptr != NULL)
   {
       // insert into array
       v[i] = atoi(ptr);
      ++i;
      // get next number from the string
      ptr = strtok(NULL, " ");
    }
    // now do something with these numbers

}

From a purely style issue, I would not use memset() nor strtok() . memset() is not necessary because you should be using only the array values you've loaded so you shouldn't have problems with uninitialized variables. As for strtok() I prefer to parse the values by hand with loops. For example:

do
{
    fgets(line, sizeof(line), f) != NULL)
    n = 0;
    // skip leading whitespace
    while (isspace(line[n])) n++;

    i = 0;
    do
    {
        // extract numbers from line string
        v[i] = atoi(&line[n]);

        // skip to next value
        while (!isspace(line[n])) n++;  // skip over this value
        while ( isspace(line[n])) 
        {
            if (line[n] == '\n')  break;  // isspace() sees \n as whitespace
            n++;  // skip over the spaces
        }
    } while( line[n] != '\n')

I feel I have more control over the input by doing essentially what strtok() does anyway. As I said, purely a personal style issue.

Now, about your code:

#include<conio.h>    //// should not use this header, not portable
#include<stdio.h>
main()
{
    clrscr();       //// Not portable.  Also in Standard C you cannot use 
                    //// an executable command before your declarations
    int v[10],v1[10],i=0,j,t,k,number,count=0;
    FILE *f ;
    f = fopen("numbers.inp", "r");   //// please use whitespace
     do
     {
        i++;
        fscanf (f, "%d", &v[i]);    //// please use whitespace for readability
        count++;
     }
     while((number=getc(f))!=EOF);

As ADragon said, fscanf() cannot distinguish end of lines. So you just read all the numbers into your 10-value array and corrupted memory.

One thing you might want to consider for debugging is using printf() 's to display pertinent values as your program executes. Then you would have seen immediately that i was getting too large for your array. You still may not know how to fix it, but at least you know what's happening.

fscanf() does not differentiate between rows. So you will be better off not using that function at all. Instead, I would use fgets() to read one row at a time then parse the string that was read.

char line[80];
char *ptr = 0;
int i = 0;

while( fgets(line, sizeof(line), f) != NULL)
{
   // clear the array
   memset(v,0,sizeof(v));
   i = 0;
   // extract numbers from line string
   ptr = strtok(line," ");
   while( ptr != NULL)
   {
       // insert into array
       v[i] = atoi(ptr);
      ++i;
      // get next number from the string
      ptr = strtok(NULL, " ");
    }
    // now do something with these numbers

}

... but it stop reading at the first line and not jump to second line. Could you help me at this point?
thank you!

... but it stop reading at the first line and not jump to second line. Could you help me at this point?
thank you!

Since the only code you posted above is ADragon's code, and his works fine, we have no idea what's wrong with yours.

<< mistake >>

... but it stop reading at the first line and not jump to second line. Could you help me at this point?
thank you!

I've experienced problems with fgets() not stopping at each line before. It turns out that the file I was using was from MacOS 9, which used a totally different encoding for newlines, and that was what screwed up fgets().

So if you didn't create the textfile yourself, consider recreating it just to be sure.

Files transferred to MS-Windows from *nix will also have that problem unless the file is run through a translation program. Most FTP programs can correctly translate the file during file transfer operation.

I have just finished my program! Thank you all of you :D

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.