Question about read data from a text file.

Discussion in 'C Programming' started by bowlderster, Apr 4, 2007.

  1. bowlderster

    bowlderster Guest

    Hello, all.

    This is the text file named test.txt.

    1041 1467 7334 9500 2169 7724 3478 3358 9962 7464
    6705 2145 6281 8827 1961 1491 3995 3942 5827 6436
    6391 6604 4902 1153 1292 4382 9421 1716 2718 2895

    I wanna to read the data to an array, as the follows:

    #include <stdio.h>
    #define MAX 30
    int main()
    {
    int i = 0 ;
    FILE *fp ;
    int a[30] = {0};
    if( (fp = fopen("test.txt", "r")) == NULL )
    printf("Open file fail!!!\n");
    for(i = 0 ; i < MAX ; i++)
    {
    fscanf(fp, "%i", &a) ;
    printf("%i\t",a);
    }
    fclose(fp);
    return 0;
    }

    It is successful.

    And I change the type of the array to float
    ....
    float a[30];
    ....
    fscanf(fp,"%f",&a);
    printf("%f\t",a);
    ....

    It works as well.

    But when I change the type of the array to double
    ....
    double a[30];
    ....
    fscanf(fp,"%g",&a);
    printf(fp,"%g",a);
    ....

    It cannot work. It seams that the array is zero.

    I wanna to know the reason and how can read the data to a double array.This is one question.

    Another is that:
    If the data file test.txt is in the following format,
    a b c d e f g h i j
    =============================================
    1041 1467 7334 9500 2169 7724 3478 3358 9962 7464
    6705 2145 6281 8827 1961 1491 3995 3942 5827 6436
    6391 6604 4902 1153 1292 4382 9421 1716 2718 2895

    how to read the file directly to the 3rd line? I mean that I just wanna to read the numbers.

    I know fseek function can move the file pointer to a certain position.
    But for a text file, how to caculate he offset?
    If it can work, please give me your example for the above file.


    I am learning the language at the beginning. Any encouragement will be helpful.
     
    bowlderster, Apr 4, 2007
    #1
    1. Advertising

  2. bowlderster

    Army1987 Guest

    "bowlderster" <> ha scritto nel messaggio
    news:...
    [snip]

    > if( (fp = fopen("test.txt", "r")) == NULL )
    > printf("Open file fail!!!\n");

    If I redirect the output to a file, I won't be able to read the error until
    I read that file.
    You must write to stderr, not stdin. If you use perror() it will also add a
    colon, a space, an explaination of the error, and a newline char.
    perror("Open file fail");
    Also, if the test fails, the rest of the program will run as if fp wasn't
    NULL.
    use exit(EXIT_FAILURE); (you must #include <stdlib.h> for these).

    > for(i = 0 ; i < MAX ; i++)
    > {
    > fscanf(fp, "%i", &a) ;
    > printf("%i\t",a);
    > }
    > fclose(fp);
    > return 0;
    > }
    >
    > It is successful.
    >
    > And I change the type of the array to float
    > ...
    > float a[30];
    > ...
    > fscanf(fp,"%f",&a);
    > printf("%f\t",a);
    > ...
    >
    > It works as well.
    >
    > But when I change the type of the array to double
    > ...
    > double a[30];
    > ...
    > fscanf(fp,"%g",&a);
    > printf(fp,"%g",a);
    > ...
    >
    > It cannot work. It seams that the array is zero.
    >
    > I wanna to know the reason and how can read the data to a double
    > array.This is one question.
    >
    > Another is that:
    > If the data file test.txt is in the following format,
    > a b c d e f g h i j
    > =============================================
    > 1041 1467 7334 9500 2169 7724 3478 3358 9962 7464
    > 6705 2145 6281 8827 1961 1491 3995 3942 5827 6436
    > 6391 6604 4902 1153 1292 4382 9421 1716 2718 2895
    >
    > how to read the file directly to the 3rd line? I mean that I just wanna to
    > read the numbers.
    >
    > I know fseek function can move the file pointer to a certain position.
    > But for a text file, how to caculate he offset?
    > If it can work, please give me your example for the above file.
    >
    >
    > I am learning the language at the beginning. Any encouragement will be
    > helpful.
    >
    >
     
    Army1987, Apr 5, 2007
    #2
    1. Advertising

  3. bowlderster

    Army1987 Guest

    "bowlderster" <> ha scritto nel messaggio
    news:...
    [snip]
    >int a[30] = {0};

    You meant a[MAX]. If you change MAX at the beginning and forget to change 30
    here, that could be a problem.

    > if( (fp = fopen("test.txt", "r")) == NULL )
    > printf("Open file fail!!!\n");

    If I redirect the output to a file, I won't be able to read the error until
    I read that file.
    You must write to stderr, not stdin. If you use perror() it will also add a
    colon, a space, an explaination of the error, and a newline char.
    perror("Open file fail");
    Also, if the test fails, the rest of the program will run as if fp wasn't
    NULL.
    use exit(EXIT_FAILURE); (you must #include <stdlib.h> for these), or even
    just return EXIT_FAILURE as you are in main()

    > But when I change the type of the array to double
    > ...
    > double a[30];
    > ...
    > fscanf(fp,"%g",&a);
    > printf(fp,"%g",a);
    > ...
    >
    > It cannot work. It seams that the array is zero.

    http://c-faq.com/stdio/scanf2.html
     
    Army1987, Apr 5, 2007
    #3
  4. In article <>,
    bowlderster <> wrote:
    >If the data file test.txt is in the following format,
    >a b c d e f g h i j
    >=============================================
    >1041 1467 7334 9500 2169 7724 3478 3358 9962 7464
    >6705 2145 6281 8827 1961 1491 3995 3942 5827 6436
    >6391 6604 4902 1153 1292 4382 9421 1716 2718 2895


    >how to read the file directly to the 3rd line? I mean that I just wanna to read the numbers.


    >I know fseek function can move the file pointer to a certain position.
    >But for a text file, how to caculate he offset?


    You cannot do that. As the local man page says for fseek()

    The ANSI C Standard restricts the use of offsets, when stream refers to a
    text file. When operating on these files, the value of offset must be
    zero unless whence is SEEK_SET. This restriction is necessary as the
    unit of offsets may not be bytes on some systems, and arithmetic may not
    meaningfully be performed on them.

    And if you are using SEEK_SET on a text stream, then the value
    you pass in must be the result of an ftell(), and ftell() on
    a text stream theoretically returns an opaque value, not an
    integral offset value.

    Text files are not necessarily linearly structured (e.g., on the
    VMS operating system), and even on systems that do structure text
    files linearly, there is no way to query what the line termination
    sequence is. (You can also run into issues such as the possibility
    that the OS might consider as a valid line termination one or more
    carriage returns before a linefeed; the first line might happen to
    end CR LF internally, but the second line might happen to end
    CR CR CR CR LF internally, so you cannot assign any fixed
    predictable size for line termination offset calculations.)


    If you were willing to lose portability and only deal with
    systems that did use linear text files, and on which you knew
    that the line termination was always the same size, then you
    could read the file as a binary file and calculate byte offsets
    if you knew the exact length of the first and second lines ahead
    of time. But there is no portable way to fseek() to any given
    line in a text stream -- not that doesn't involve reading
    the file through once to find all the line offsets.
    --
    If you lie to the compiler, it will get its revenge. -- Henry Spencer
     
    Walter Roberson, Apr 5, 2007
    #4
  5. bowlderster

    Michael Guest

    On Apr 4, 3:20 pm, bowlderster <> wrote:
    > This is the text file named test.txt.
    >
    > 1041 1467 7334 9500 2169 7724 3478 3358 9962 7464
    > 6705 2145 6281 8827 1961 1491 3995 3942 5827 6436
    > 6391 6604 4902 1153 1292 4382 9421 1716 2718 2895
    >
    > I wanna to read the data to an array, as the follows:
    >
    > #include <stdio.h>
    > #define MAX 30
    > int main()
    > {
    > int i = 0 ;
    > FILE *fp ;
    > int a[30] = {0};
    > if( (fp = fopen("test.txt", "r")) == NULL )
    > printf("Open file fail!!!\n");
    > for(i = 0 ; i < MAX ; i++)
    > {
    > fscanf(fp, "%i", &a) ;
    > printf("%i\t",a);}
    >
    > fclose(fp);
    > return 0;
    >
    > }
    >
    > But when I change the type of the array to double
    > ...
    > double a[30];
    > ...
    > fscanf(fp,"%g",&a);
    > printf(fp,"%g",a);
    > ...
    >
    > It cannot work. It seams that the array is zero.


    fscanf(fp, "%lf", &a) ;

    > Another is that:
    > If the data file test.txt is in the following format,
    > a b c d e f g h i j
    > =============================================
    > 1041 1467 7334 9500 2169 7724 3478 3358 9962 7464
    > 6705 2145 6281 8827 1961 1491 3995 3942 5827 6436
    > 6391 6604 4902 1153 1292 4382 9421 1716 2718 2895
    >
    > how to read the file directly to the 3rd line? I mean that I just wanna to read the numbers.


    You could use fgets (twice) to read each of the first two lines.

    Michael
     
    Michael, Apr 5, 2007
    #5
  6. bowlderster

    bowlderster Guest

    "Army1987" <> writes:

    > "bowlderster" <> ha scritto nel messaggio
    > news:...
    > [snip]
    >>int a[30] = {0};

    > You meant a[MAX]. If you change MAX at the beginning and forget to change 30
    > here, that could be a problem.

    Thanks.I just want to test.

    >
    >> if( (fp = fopen("test.txt", "r")) == NULL )
    >> printf("Open file fail!!!\n");

    > If I redirect the output to a file, I won't be able to read the error until
    > I read that file.
    > You must write to stderr, not stdin. If you use perror() it will also add a
    > colon, a space, an explaination of the error, and a newline char.
    > perror("Open file fail");
    > Also, if the test fails, the rest of the program will run as if fp wasn't
    > NULL.
    > use exit(EXIT_FAILURE); (you must #include <stdlib.h> for these), or even
    > just return EXIT_FAILURE as you are in main()
    >
    >> But when I change the type of the array to double
    >> ...
    >> double a[30];
    >> ...
    >> fscanf(fp,"%g",&a);
    >> printf(fp,"%g",a);
    >> ...
    >>
    >> It cannot work. It seams that the array is zero.

    > http://c-faq.com/stdio/scanf2.html


    This is helpful.

    Thank you.
     
    bowlderster, Apr 5, 2007
    #6
  7. bowlderster

    bowlderster Guest

    -cnrc.gc.ca (Walter Roberson) writes:

    > In article <>,
    > bowlderster <> wrote:
    >>If the data file test.txt is in the following format,
    >>a b c d e f g h i j
    >>=============================================
    >>1041 1467 7334 9500 2169 7724 3478 3358 9962 7464
    >>6705 2145 6281 8827 1961 1491 3995 3942 5827 6436
    >>6391 6604 4902 1153 1292 4382 9421 1716 2718 2895

    >
    >>how to read the file directly to the 3rd line? I mean that I just wanna to read the numbers.

    >
    >>I know fseek function can move the file pointer to a certain position.
    >>But for a text file, how to caculate he offset?

    >
    > You cannot do that. As the local man page says for fseek()
    >
    > The ANSI C Standard restricts the use of offsets, when stream refers to a
    > text file. When operating on these files, the value of offset must be
    > zero unless whence is SEEK_SET. This restriction is necessary as the
    > unit of offsets may not be bytes on some systems, and arithmetic may not
    > meaningfully be performed on them.
    >
    > And if you are using SEEK_SET on a text stream, then the value
    > you pass in must be the result of an ftell(), and ftell() on
    > a text stream theoretically returns an opaque value, not an
    > integral offset value.
    >
    > Text files are not necessarily linearly structured (e.g., on the
    > VMS operating system), and even on systems that do structure text
    > files linearly, there is no way to query what the line termination
    > sequence is. (You can also run into issues such as the possibility
    > that the OS might consider as a valid line termination one or more
    > carriage returns before a linefeed; the first line might happen to
    > end CR LF internally, but the second line might happen to end
    > CR CR CR CR LF internally, so you cannot assign any fixed
    > predictable size for line termination offset calculations.)
    >
    >
    > If you were willing to lose portability and only deal with
    > systems that did use linear text files, and on which you knew
    > that the line termination was always the same size, then you
    > could read the file as a binary file and calculate byte offsets
    > if you knew the exact length of the first and second lines ahead
    > of time. But there is no portable way to fseek() to any given
    > line in a text stream -- not that doesn't involve reading
    > the file through once to find all the line offsets.
    > --
    > If you lie to the compiler, it will get its revenge. -- Henry Spencer


    I know a lot from your words.
     
    bowlderster, Apr 5, 2007
    #7
  8. bowlderster wrote:

    > This is the text file named test.txt.
    >
    > 1041 1467 7334 9500 2169 7724 3478 3358 9962 7464
    > 6705 2145 6281 8827 1961 1491 3995 3942 5827 6436
    > 6391 6604 4902 1153 1292 4382 9421 1716 2718 2895
    >
    > I wanna to read the data to an array, as the follows:


    "want to" standard english is easier to read.

    code is more readable if indented and with appropriate whitespace

    > #include <stdio.h>
    > #define MAX 30
    >
    > int main()


    int main (void)
    is better style

    > {
    > int i = 0 ;
    > FILE *fp ;
    > int a[30] = {0};
    >
    > if ( (fp = fopen("test.txt", "r")) == NULL )
    > printf("Open file fail!!!\n");
    >
    > for (i = 0 ; i < MAX ; i++)
    > {
    > fscanf(fp, "%i", &a) ;


    always check the return value of fscanf()


    > printf("%i\t",a);
    > }
    >
    > fclose(fp);
    > return 0;
    > }


    <snip>

    > I am learning the language at the beginning. Any encouragement will be helpful.


    not bad for a beginner


    --
    Nick Keighley
     
    Nick Keighley, Apr 5, 2007
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Krish
    Replies:
    1
    Views:
    1,102
    =?Utf-8?B?Q3VydF9DIFtNVlBd?=
    Oct 20, 2005
  2. Replies:
    2
    Views:
    646
    Thomas Matthews
    Feb 27, 2007
  3. Mmcolli00 Mom
    Replies:
    2
    Views:
    210
    Mmcolli00 Mom
    Jan 27, 2009
  4. Alex Dowad
    Replies:
    4
    Views:
    299
    Michel Demazure
    May 1, 2010
  5. Replies:
    19
    Views:
    256
    Andreas Perstinger
    Oct 7, 2013
Loading...

Share This Page