이름이 텍스트 파일이 있습니다. 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);
}
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()
with %s
as 형식 의 방법은 파일의 공백에 대한 정보를 잃어 버리기 때문에 파일을 stdout
.
답변
여기에는 청크로 읽는 것에 대한 좋은 답변이 많이 있습니다. 모든 내용을 한 번에 버퍼로 읽어서 인쇄하는 작은 트릭을 보여 드리겠습니다.
더 낫다는 말이 아닙니다. 그렇지 않고 Ricardo가 때때로 나쁠 수 있지만 간단한 경우에는 좋은 해결책이라고 생각합니다.
많은 일이 일어나고 있기 때문에 코멘트를 뿌렸습니다.
#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;
}
유용하거나 배울 수 있는지 알려주세요 🙂
답변
대신 텍스트 파일이 매우 클 수 있고 많은 메모리가 필요할 수 있으므로 문자를 콘솔에 직접 인쇄하십시오.
#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;
}
답변
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
하여 한 번에 한 문자 씩 읽고 쓰는 것입니다. 훨씬 덜 효율적입니다. 좋은 예 : http://www.eskimo.com/~scs/cclass/notes/sx13.html
답변
두 가지 접근 방식이 떠 오릅니다.
첫째, scanf
. 사용 fgets()
버퍼 크기를 지정하는 매개 변수를, 그대로 어떤 개행 문자를 떠난다. 버퍼 내용을 인쇄하는 파일에 대한 간단한 루프는 자연스럽게 파일을 그대로 복사해야합니다.
둘째, 사용 fread()
또는 함께 일반적인 C 관용구 fgetc()
. 이들은 파일을 고정 된 크기의 청크 또는 한 번에 하나의 문자로 처리합니다.
공백으로 구분 된 문자열을 통해 파일을 처리해야하는 경우 fgets
또는 중 하나를 사용 fread
하여 파일을 읽고 strtok
버퍼를 공백으로 분할하는 것과 같은 방법 을 사용하십시오. 대상 문자열이 버퍼 경계에 걸쳐있을 가능성이 있으므로 한 버퍼에서 다음 버퍼로의 전환을 처리하는 것을 잊지 마십시오.
scanf
읽기를 수행하는 데 사용할 외부 요구 사항이 있는 경우 형식 지정자의 정밀도 필드를 사용하여 읽을 수있는 문자열의 길이를 제한합니다. 999 바이트 버퍼 scanf("%998s", str);
를 사용하는 경우 nul 종결자를위한 공간을 남겨두고 버퍼에 최대 998 문자를 쓸 것이라고 말 하십시오. 버퍼보다 긴 단일 문자열이 허용되는 경우 두 부분으로 처리해야합니다. 그렇지 않은 경우 버퍼 오버플로 보안 구멍을 만들지 않고 정중하게 오류에 대해 사용자에게 알릴 수 있습니다.
어쨌든 항상 반환 값의 유효성을 검사하고 잘못되거나 악의적이거나 잘못된 입력을 처리하는 방법에 대해 생각하십시오.
답변
fgets
읽기 문자열의 크기를 사용 하고 제한 할 수 있습니다 .
char *fgets(char *str, int num, FILE *stream);
while
코드에서를 다음과 같이 변경할 수 있습니다 .
while (fgets(str, 100, file)) /* printf("%s", str) */;
답변
동적 메모리 할당으로 전체 파일을 읽을 수 있지만 파일이 너무 크면 메모리 문제가 발생할 수 있기 때문에 좋은 생각이 아닙니다.
따라서 파일의 짧은 부분을 읽고 인쇄하는 것이 좋습니다.
#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;
}