source

C에서 텍스트 파일을 읽고 모든 문자열을 인쇄하려면 어떻게 해야 합니까?

itover 2022. 12. 1. 21:31
반응형

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그것보다 클 수 있습니다.어떻게 하면 해결할 수 있을까요?

가장 간단한 방법은 문자를 읽고 읽은 후 바로 인쇄하는 것입니다.

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

cint위에서부터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 \0 in the last position
       // and buffer is now officially a string
       buffer[string_size] = '\0';

       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;
}

도움이 되는지, 뭔가 배울 점이 있는지 알려주세요.

fscanf 대신 "read()"를 사용합니다.

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.124

읽기 문자열의 크기를 제한하고 사용할 수 있습니다.

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

를 변경할 수 있습니다.while코드 입력:

while (fgets(str, 100, file)) /* printf("%s", str) */;

텍스트 파일이 매우 크고 메모리가 많이 필요할 수 있으므로 콘솔에 직접 문자를 인쇄하는 것이 좋습니다.

#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;
}

두 가지 접근법이 갑자기 떠오릅니다.

첫째, 사용하지 말 것scanf.사용하다fgets()버퍼 크기를 지정하기 위한 파라미터를 사용하여 줄바꿈 문자를 그대로 유지합니다.버퍼 내용을 인쇄하는 파일 위에 간단한 루프를 설치하면 파일이 그대로 복사됩니다.

번째, 째, 사를 사용합니다.fread() 'C'가 붙은 인 C 관용어fgetc()하거나 한 한 처리합니다 이들은 파일을 고정 크기 청크로 처리하거나 한 번에 한 글자씩 처리합니다.

문자열로 해야 하는 , " " " " " " 를 하십시오.fgets ★★★★★★★★★★★★★★★★★」fread, 읽다, 읽다, 읽다, 읽다, 읽다.strtok이치노타겟 문자열이 버퍼 경계에 걸쳐 있을 가능성이 높기 때문에 버퍼에서 다음 버퍼로의 이행을 처리하는 것을 잊지 마십시오.

, 「」를 사용해 주세요.scanf읽기를 수행하려면 형식 지정자의 정밀도 필드를 사용하여 읽을 수 있는 문자열 길이를 제한합니다.에는 999라고 .scanf("%998s", str);최대 998자까지 버퍼에 쓰기 때문에 nul 터미네이터에 여유가 생깁니다.버퍼보다 긴 단일 문자열을 사용할 수 있는 경우 두 부분으로 나누어 처리해야 합니다.그렇지 않으면 버퍼 오버플로 보안 구멍을 만들지 않고 사용자에게 오류에 대해 정중하게 알릴 수 있습니다.

단, 항상 반환값을 검증하고 잘못된 입력, 악의적인 입력 또는 잘못된 형식의 입력을 처리하는 방법을 고려하십시오.

동적 메모리 할당으로 전체 파일을 읽을 수 있지만 파일이 너무 크면 메모리 문제가 발생할 수 있으므로 권장하지 않습니다.

따라서 파일의 짧은 부분을 읽고 인쇄하는 것이 좋습니다.

#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;
}

를 사용하면 큰 줄을 신경 쓰지 않고 텍스트 파일을 읽을 수 있습니다.

bool read_file(const char *filename)
{
    FILE *file = fopen(filename, "r");
    if (!file)
        return false;
    
    char *line = NULL;
    size_t linesize = 0;

    while (getline(&line, &linesize, file) != -1)
        printf("%s", line);
    
    free(line);
    fclose(file);

    return true;
}

다음과 같이 사용할 수 있습니다.

int main(void)
{
    if (!read_file("test.txt")) {
        printf("Error reading file\n");
        exit(EXIT_FAILURE);
    }
}

이 버전을 사용합니다.

char* read(const char* filename){
    FILE* f = fopen(filename, "rb");
    if (f == NULL){
        exit(1);
    }
    fseek(f, 0L, SEEK_END);
    long size = ftell(f)+1;
    fclose(f);
    f = fopen(filename, "r");
    void* content = memset(malloc(size), '\0', size);
    fread(content, 1, size-1, f);
    fclose(f);
    return (char*) content;
}

언급URL : https://stackoverflow.com/questions/3463426/in-c-how-should-i-read-a-text-file-and-print-all-strings

반응형