2014-10-11 97 views
-1

比方说,我有这样的使用FREAD和FSEEK

一个文本文件,这是一个文本文件,其中包含一些数字阅读文本文件中的字符的具体数量。

所以我想用fseek和fread来读取文本文件的某些部分。 例如,从位置0到13,我会得到“这是一个文本”。 然后从位置14到24,我会得到“文件”,然后从位置25到文件结尾,我会得到“包含一些数字”。

我试过使用fseek和fread,但我有一些额外的奇怪的字符,如“这是一个文本?”

我尝试使用FSEEK和FREAD:

src = fopen(textfile, "r"); 
int chunksize = data[i].end - data[i].start; 
char *buffer = malloc(sizeof(chunksize)); 

seek(src, data[i].start, SEEK_SET); 
fread(buffer, 1, chunksize, src); 
fseek(src, 0, SEEK_SET); // seek back to beginning of file  

其中data[i].start是起始位置读取到的部分和data[i].end是结束位置停止。例如,从14日到24日,我会得到“文件”。开始是14和结束是25

+1

'的malloc(的sizeof(CHUNKSIZE))'是错误的 - '的sizeof(CHUNKSIZE)==的sizeof(int)的'是编译时常量。删除'sizeof'。你需要显示你用来显示数据的代码,以及(暗示)你是如何终止它的。 – Mat 2014-10-11 20:15:12

+1

而且,除了Mat的注释,还提供了您正在使用的输入文件。 – ryyker 2014-10-11 20:17:10

回答

2

您需要大约重写代码如下:

src = fopen(textfile, "r"); 
int chunksize = ... 
char *buffer = malloc(chunksize + 1); 
fseek(src, data[i].start, src); 
int len = fread(buffer, 1, chunksize, src); 
*(buffer+len) = '\0'; 

所以,我们有以下的,包含什么从文件中读取的缓冲区。我们在读取内容之后有一个字符串终结符(可能比您要求的要少)。如果你现在问题:

print("%s\n", buffer) 

你会得到你从文件中读到的东西。

PS:这是一个好主意,检查从fopen()回报,以确保文件正确打开,并从malloc()回报,以确保内存已成功分配,并从fread()回报,以确保正确的数据量被读取。

0

数据结束后的随机字符由非null终止输入字符串或不限制输出为读取的数据而产生。 fread()不会'空'终止'它读取的内容;如果有的话,这将是无用的。

您正在分配的内存太少。您有:

char *buffer = malloc(sizeof(chunksize)); 

您需要:

char *buffer = malloc(chunksize); 

或者你可以分配一个额外的字节和存储空字节在'\0'。如果你将需要将它传递给需要的字符串编码,这样比较好:

char *buffer = malloc(chunksize + 1); 

你应该检查的大部分功能的错误回报;具体而言,您应该注意malloc(),fopen()fread()。您还需要使用fseek(),而不是seek()

您可以使用:

src = fopen(textfile, "r"); 
if (src == 0) 
    err_exit("Failed to open %s for reading\n", textfile); 

int chunksize = data[i].end - data[i].start; 
char *buffer = malloc(chunksize + 1); 
if (buffer == 0) 
    err_exit("Failed to allocate %d bytes memory\n", chunksize); 

fseek(src, data[i].start, SEEK_SET); 
size_t nbytes = fread(buffer, 1, chunksize, src); 
fseek(src, 0, SEEK_SET); 
buffer[nbytes] = '\0'; 
if (nbytes != 0) 
    printf("Read: <<%.*s>>\n", (int)nbytes, buffer); 

或:

prinf("Read: <<%s>>\n", buffer); 
+0

在文本文件UB中不是'fseek()',除非从开头或前一个'ftell()'寻找? – chux 2014-10-12 04:59:12

+0

如果你在Windows上;是的(至少在理论上)。如果你在一个理智的系统上;没有。问题是CRLF到NL映射;你可能会寻求CRLF中间的东西,或者其他东西。我不确定在任何实际系统中是否存在真正的问题 - 您是否有反例? – 2014-10-12 05:00:31

+0

没有在C11中找到对Windows的引用7.21.9.2 4“对于文本流,任一偏移量应为零,或者偏移量应为先前成功调用与同一文件关联的流上的ftell函数所返回的值从哪里来SEEK_SET。“ – chux 2014-10-12 05:04:23