2013-07-16 3 views
2

Я пытаюсь прочитать в файле, hello.ms, содержащий следующее:Fread пропускает первые 8 символов

Hello World! 

Используя этот код С:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int store_file(char* file_dir, char** buffer) 
{ 
    FILE* file; 
    long lSize; 
    size_t result; 
    char* tempBuffer; 

    file = fopen(file_dir, "r"); 
    if (file==NULL) 
    { 
     fputs("File error.", stderr); 
     exit(1); 
    } 

    fseek(file, 0, SEEK_END); 
    lSize = ftell(file); 
    rewind(file); 

    tempBuffer = (char*)malloc(sizeof(char)*lSize); 
    if (tempBuffer == NULL) 
    { 
     fputs("Memory error.", stderr); 
     exit(2); 
    } 

    result = fread(tempBuffer, 1, lSize, file); 
    if (result != lSize) 
    { 
     fputs("Reading error.", stderr); 
     exit(3); 
    } 

    *buffer = tempBuffer; 
    free(tempBuffer); 
    fclose(file); 

    return lSize; 
} 

void fsa_cycle(char* file_dir) 
{ 
    char* buffer; 
    int bufferSize = store_file(file_dir, &buffer); 

    fwrite(buffer, sizeof(char), bufferSize, stdout); 
} 

int main(int argc, char* argv[]) 
{ 
    if(argc < 2) 
    { 
     printf("\nSyntax: %s <file-name>\n\n", argv[0]); 
     exit(1); 
    } 

    fsa_cycle(argv[1]); 

    return 0; 
} 

Он компилирует прекрасно. Нет предупреждений или ошибок. Но он выводит только rld!

При добавлении 8 пробелов в файл hello.ms, он считывает Hello World!

Может кто-нибудь сказать мне, почему это происходит? Я попробовал написать fseek (файл, 0, SEEK_CUR) вместо перемотки, но это тоже не сработало. Я не нашел никакой помощи в Google, которая не предполагала, что программист забыл использовать fseek для начала. Любая помощь была бы потрясающей!

+0

не FOPEN при открытии с «г» гарантии, что индикатор положения будет в начале файла? Вы пробовали просто расширять файл и читать его без каких-либо поисков? –

+0

Почему вы ищете? Просто используйте Fgets: fgets() читает не более одного символа размера из потока и сохраняет их в буфер, на который указывает s. Чтение останавливается после EOF или новой строки. Если читается новая строка, она сохраняется в буфере. Конечный нулевой байт (aq \ 0aq) сохраняется после последнего символа в буфере. – Magn3s1um

+0

@ScottyBauer Ну, причина, по которой вы ищете, - это найти размер файла, на который я верю. Чтобы установить переменную lSize no? Однако я не эксперт. – eatonphil

ответ

3

Вы используете free для освобождения памяти tempBuffer, но этот блок памяти фактически назначен buffer.

free могут работать разные с разными компиляторами, а мои работы, как ваша, просто удалить free(tempBuffer);

+0

Документация, которую я читал, говорит о том, что после malloc важно было освободить tempBuffer после того, как я закончил с ним. Если не там, где будет подходящее место для освобождения этой памяти? Или мне не нужно беспокоиться об этом, потому что я назначаю ему буфер? – eatonphil

+0

Вы не «сделали это» до тех пор, пока не напишите его в 'stdout' в' fsa_cycle'. – Casey

+0

'* buffer = tempBuffer;' означает, что оба указателя указывают на один и тот же блок памяти. используйте 'free (...)', когда вам больше не нужен этот блок памяти, это значит, что вам не нужны 'tempBuffer' и' buffer' –

1

Я побежал в БГД и дела идут плохо после того, как свободный (tempBuffer);

(GDB) 31, если (результат! = LSize)

(GDB) печати tmpBuffer

Нет символа "tmpBuffer" в текущем контексте.

(GDB) печати tempBuffer

$ 3 = 0x602250 "Hello World! \ П"

(GDB) п

37 * буфер = tempBuffer;

(GDB)

38 бесплатно (tempBuffer);

(GDB) печать буфера

$ 4 = (символ **) 0x7fffffffe180

(GDB) печать * буфер

$ 5 = 0x602250 «Hello World!\ П»

(GDB) п

39 fclose (файл);

(GDB)

41 Возвращение lSize;

(GDB) печать * буфер

$ 6 = 0x602250 ""

(gdb) print tempBuffer

$ 7 = 0x602250 ""

2

Вы освобождаете буфер слишком рано.
Вы должны освободить память после использования буфера. Линия:

fwrite(buffer, sizeof(char), bufferSize, stdout); 
0

пытаются использовать таким образом

char *buff; 
buff = calloc(sizeOfFileInBytes + 1, sizeof(char));//replace sizeOfFileInBytes with file size (use stat to get file size) 
if (!buff) { 
    printf("error : %s", strerror(errno)); 
    fclose(f); 
} 
fread(buff, sizeOfFileInBytes, 1, f); 

fclose(f); 
printf("%s\n", (char *) buff);//lets echo what we get from fread; 
free(buff);//lets return memory to heap 
Смежные вопросы