向后阅读文本文件并放入C语言

时间:2015-12-09 13:54:02

标签: c

  

我想知道如何在C中向后阅读文本文件。

Frozen_snowman.txt是

Do you wanna build a snowman?
Come on lets go and play
I never see you anymore
Come out the door
It's like you've gone away-
We used to be best buddies
And now we're not
I wish you would tell me why!-
Do you wanna build a snowman?
It doesn't have to be a snowman.

代码

#include<stdio.h>
int main()
{
    int i;
    char buffer[100];
    char *a[100];
    FILE *f,*p;
    f=fopen("Frozen_snowman.txt","r");
    p=fopen("Reverse.txt","w");
    for(i=0;i<10;i++)
    {
        fgets(buffer,100,f);
        a[i]=buffer;
    }
    for(i=9;i>-1;i--)
    {
        fputs(a[i],p);
    }

    return 0;   
}

结果是

It doesn't have to be a snowman.
It doesn't have to be a snowman.
It doesn't have to be a snowman.
It doesn't have to be a snowman.
It doesn't have to be a snowman.
It doesn't have to be a snowman.
It doesn't have to be a snowman.
It doesn't have to be a snowman.
It doesn't have to be a snowman.
It doesn't have to be a snowman.
  

为什么?

3 个答案:

答案 0 :(得分:1)

原因是这个 -

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0xffffffffffffffe8

VM Regions Near 0xffffffffffffffe8:
--> shared memory          00007fffffe36000-00007fffffe37000 [    4K] r-x/r-x SM=SHM  


Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libc++.1.dylib                  0x00007fff8fb6c4f1 std::__1::basic_istream<char, std::__1::char_traits<char> >::sentry::sentry(std::__1::basic_istream<char, std::__1::char_traits<char> >&, bool) + 29
1   libc++.1.dylib                  0x00007fff8fb6e437 std::__1::basic_istream<char, std::__1::char_traits<char> >::tellg() + 191
2   ???                             0x000000010d0b44ee 0 + 4513809646
3   ???                             0x000000010d0b35d8 0 + 4513805784
4   ???                             0x000000010d1213cd 0 + 4514255821
5   ???                             0x000000010d18e5c7 0 + 4514702791
6   ???                             0x000000010d159251 0 + 4514484817
7   ???                             0x000000010d18df0a 0 + 4514701066
8   ???                             0x000000010d144b1a 0 + 4514401050
9   ???                             0x000000010d0b121a 0 + 4513796634
10  ???                             0x000000010d0b66b1 0 + 4513818289
11  dyld                            0x00007fff659f1d0b ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) + 265
12  dyld                            0x00007fff659f1e98 ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) + 40
13  dyld                            0x00007fff659ee891 ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 305
14  dyld                            0x00007fff659ee718 ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 138
15  dyld                            0x00007fff659ee989 ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) + 75
16  dyld                            0x00007fff659e1245 dyld::initializeMainExecutable() + 187
17  dyld                            0x00007fff659e4c19 dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) + 2669
18  dyld                            0x00007fff659e0276 dyldbootstrap::start(macho_header const*, int, char const**, long, macho_header const*, unsigned long*) + 512
19  dyld                            0x00007fff659e0036 _dyld_start + 54

您指向存储在上一次迭代fgets(buffer,100,f); // check return of fgets a[i]=buffer; // Note - buffer is modified in each iteration 的字符串。每个指针指向最后一个字符串读取。每次打印相同的字符串都会打印出来。

你应该做的是将内存分配给指针buffer,并使用a[i]复制字符串。

答案 1 :(得分:0)

如果你知道它总是10行,你可以声明一个2d数组。

这样的事情会更好。

#include<stdio.h>
#include<string.h>
int main()
{
    int i;
    char buffer[100];
    char a[10][100];
    FILE *f,*p;
    f=fopen("Frozen_snowman.txt","r");
    p=fopen("Reverse.txt","w");
    for(i=0;i<10;i++)
    {
        fgets(buffer,100,f);
        strcpy (a[i], buffer);
    }
    for(i=9;i>-1;i--)
    {
        fputs(a[i],p);
    }

    return 0;   
}

答案 2 :(得分:0)

以下代码有效,编译干净,执行错误检查,反转输入文件中行的顺序,并始终自行清理。

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

#define MAX_LINES (100)

int main( void )
{
    int    i;

    char *a[MAX_LINES] = {NULL};  // initialize pointers for up to 100 lines
    FILE *fin = NULL;       // input file pointer
    FILE *fout = NULL;      // output file pointer

    if( NULL ==(fin=fopen("Frozen_snowman.txt","r") ) )
    { // then fopen failed
        perror( "fopen for input file: Frozen Snowman.txt failed");
        exit( EXIT_FAILURE );
    }

    // implied else, fopen for input successful

    if( NULL == (fout = fopen("Reverse.txt","w") ) )
    { // then fopen failed
        perror( "fopen for output file Reverse.txt failed");
        fclose( fin ); // close the file opened above
        exit( EXIT_FAILURE );
    }

    // implied else, fopen for output successful

    // read each line into allocated memory
    // and place allocated memory pointer in array
    i = 0;
    while( i < MAX_LINES && getline(&(a[i]), NULL, fin) )
    {
        i++;
    }

    // count backwards through saved lines, printing them, then
    // returning the associated memory to the 'heap'
    for(i--; i>=0; i--)
    {
        fputs( a[i],fout);
        free( a[i] );  // no longer need this line 
    }

    // close open files before exiting
    fclose( fin );
    fclose( fout );

    return 0;
} // end function: main