В 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 может быть больше, чем. Как я могу решить эту проблему?
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