我想知道如何在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.
为什么?
答案 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