В C, как я должен прочитать текстовый файл и распечатать все строки



у меня есть текстовый файл с именем test.txt



Я хочу написать программу на C, которая может прочитать этот файл и распечатать содержимое на консоль (предположим, что файл содержит только текст ASCII).



Я не знаю, как получить размер моей строковой переменной. Вот так:



char str[999];
FILE * file;
file = fopen( "test.txt" , "r");
if (file) {
while (fscanf(file, "%s", str)!=EOF)
printf("%s",str);
fclose(file);
}


в размере 999 не работает, потому что строка, возвращенная fscanf может быть больше, чем. Как я могу решить эту проблему?

537   8  

8 ответов:

самый простой способ-прочитать символ и распечатать его сразу после прочтения:

int c;
FILE *file;
file = fopen("test.txt", "r");
if (file) {
    while ((c = getc(file)) != EOF)
        putchar(c);
    fclose(file);
}

c - это int выше, так как EOF - это отрицательное число, и простой char может быть unsigned.

если вы хотите прочитать файл в кусках, но без динамического выделения памяти, вы можете сделать:

#define CHUNK 1024 /* read 1024 bytes at a time */
char buf[CHUNK];
FILE *file;
size_t nread;

file = fopen("test.txt", "r");
if (file) {
    while ((nread = fread(buf, 1, sizeof buf, file)) > 0)
        fwrite(buf, 1, nread, stdout);
    if (ferror(file)) {
        /* deal with error */
    }
    fclose(file);
}

второй метод выше по существу, как вы будете читать файл с динамически выделенным массивом:

char *buf = malloc(chunk);

if (buf == NULL) {
    /* deal with malloc() failure */
}

/* otherwise do this.  Note 'chunk' instead of 'sizeof buf' */
while ((nread = fread(buf, 1, chunk, file)) > 0) {
    /* as above */
}

ваш метод из fscanf() С %s как формат теряет информацию о пробелах в файле, так что это не совсем копирование файла в stdout.

есть много хороших ответов здесь о чтении его кусками, я просто покажу вам небольшой трюк, который читает все содержимое сразу в буфер и печатает его.

Я не говорю, что это лучше. Это не так, и как Рикардо иногда это может быть плохо, но я считаю, что это хорошее решение для простых случаев.

я посыпал его комментариями, потому что там много происходит.

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

char* ReadFile(char *filename)
{
   char *buffer = NULL;
   int string_size, read_size;
   FILE *handler = fopen(filename, "r");

   if (handler)
   {
       // Seek the last byte of the file
       fseek(handler, 0, SEEK_END);
       // Offset from the first to the last byte, or in other words, filesize
       string_size = ftell(handler);
       // go back to the start of the file
       rewind(handler);

       // Allocate a string that can hold it all
       buffer = (char*) malloc(sizeof(char) * (string_size + 1) );

       // Read it all in one operation
       read_size = fread(buffer, sizeof(char), string_size, handler);

       // fread doesn't set it so put a  in the last position
       // and buffer is now officially a string
       buffer[string_size] = '';

       if (string_size != read_size)
       {
           // Something went wrong, throw away the memory and set
           // the buffer to NULL
           free(buffer);
           buffer = NULL;
       }

       // Always remember to close the file.
       fclose(handler);
    }

    return buffer;
}

int main()
{
    char *string = ReadFile("yourfile.txt");
    if (string)
    {
        puts(string);
        free(string);
    }

    return 0;
}

Дайте мне знать, если это полезно, или вы могли бы чему-нибудь научиться :)

вместо этого просто распечатайте символы на консоли, потому что текстовый файл может быть очень большим, и вам может потребоваться много памяти.

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

int main() {

    FILE *f;
    char c;
    f=fopen("test.txt","rt");

    while((c=fgetc(f))!=EOF){
        printf("%c",c);
    }

    fclose(f);
    return 0;
}

используйте "read ()" вместо fscanf:

ssize_t read(int fildes, void *buf, size_t nbyte);

описание

функция read () должна пытаться читать nbyte байт из файла, связанного с открытым файловым дескриптором fildes, в буфер, на который указывает buf.

вот пример:

http://cmagical.blogspot.com/2010/01/c-programming-on-unix-implementing-cat.html

рабочая часть из этого пример:

f=open(argv[1],O_RDONLY);
while ((n=read(f,l,80)) > 0)
    write(1,l,n);

альтернативный подход заключается в использовании getc/putc для чтения / записи 1 символ за один раз. Гораздо менее эффективно. Хороший пример: http://www.eskimo.com/~scs/cclass/notes/sx13.html

на ум приходят два подхода.

во-первых, не используйте scanf. Используйте fgets() который принимает параметр для указания размера буфера, и который оставляет все символы новой строки нетронутыми. Простой цикл над файлом, который печатает содержимое буфера, естественно, должен скопировать файл в целости и сохранности.

во-вторых, используйте fread() или общая идиома C с fgetc(). Они будут обрабатывать файл в кусках фиксированного размера или по одному символу за раз.

если вы должны обработать файл поверх строк, разделенных пробелами, затем используйте либо fgets или fread читать файл, и что-то вроде strtok чтобы разделить буфер на пробелы. Не забудьте обработать переход от одного буфера к другому, так как ваши целевые строки, вероятно, будут охватывать границу буфера.

если есть внешнее требование использовать scanf чтобы выполнить чтение, затем ограничьте длину строки, которую он может прочитать с помощью поля точности в спецификаторе формата. В вашем случае с 999 байт буфера, а затем сказать scanf("%998s", str); который будет записывать не более 998 символов в буфер, оставляя место для Терминатора nul. Если разрешены отдельные строки длиннее вашего буфера, то вам придется обрабатывать их в двух частях. Если нет, у вас есть возможность вежливо сообщить пользователю об ошибке, не создавая дыру безопасности переполнения буфера.

независимо от этого, всегда проверяйте возвращаемые значения и думайте о том, как обрабатывать плохие, вредоносные или просто искаженные вход.

#include <stdio.h>
#include <stdlib.h>
int main() {

int num;
FILE *fptr; 



if ((fptr = fopen("/root/Desktop/my_pass.txt","r")) == NULL) {       // checks if file exists
    puts("File not exists");
    exit(1);                    // for exit(1) is required #include <stdlib.h> 
} else 

fscanf(fptr,"%d", &num);                

printf("My pass is:  %d\n", num);           
fclose(fptr); 

return 0;
}

вы можете использовать fgets и ограничить размер строки чтения.

char * fgets ( char * str, int num, FILE * stream );

в коде вы можете изменить время:

while(fgets(str, 100, file) != EOF) 

вы можете прочитать весь файл с динамическим выделением памяти, но это не очень хорошая идея, потому что если файл слишком большой, у вас могут быть проблемы с памятью.

Так что лучше прочитать короткие части файла и распечатать его.

#include <stdio.h>
#define BLOCK   1000

int main() {
    FILE *f=fopen("teste.txt","r");
    int size;
    char buffer[BLOCK];
    // ...
    while((size=fread(buffer,BLOCK,sizeof(char),f)>0)
            fwrite(buffer,size,sizeof(char),stdout);
    fclose(f);
    // ...
    return 0;
}

Comments

    Ничего не найдено.