C에서 한 줄씩 텍스트 파일을 살펴보기
나는 CIS 클래스를위한 작은 연습을 해왔고 C가 파일에서 읽는 데 사용하는 방법에 매우 혼란스러워합니다. 내가 정말로해야 할 일은 한 줄씩 파일을 읽고 각 줄에서 수집 한 정보를 사용하여 몇 가지 조작을 수행하는 것입니다. 운없이 getline 메서드와 다른 방법을 사용해 보았습니다. 내 코드는 현재 다음과 같습니다.
int main(char *argc, char* argv[]){
const char *filename = argv[0];
FILE *file = fopen(filename, "r");
char *line = NULL;
while(!feof(file)){
sscanf(line, filename, "%s");
printf("%s\n", line);
}
return 1;
}
지금은 sscanf 메서드에서 seg 오류가 발생하고 그 이유를 잘 모르겠습니다. 나는 총 C noob이고 내가 놓친 큰 그림이 있는지 궁금합니다. 감사
너무 적은 줄에 너무 많은 문제가 있습니다. 나는 아마 몇 가지를 잊었다.
- argv [0]은 첫 번째 인수가 아닌 프로그램 이름입니다.
- 변수를 읽으려면 메모리를 할당해야합니다.
- 하나는 절대로 feof를 반복하지 않고, 하나는 실패 할 때까지 IO 함수를 반복하고, feof는 실패 이유를 결정하는 역할을합니다.
- sscanf는 행을 구문 분석하기 위해 있습니다. 파일을 구문 분석하려면 fscanf를 사용하십시오.
- "% s"는? scanf 계열의 형식으로 첫 번째 공백에서 중지됩니다.
- 한 줄을 읽기 위해 표준 함수는 fgets,
- 메인에서 1을 반환하면 실패를 의미합니다.
그래서
#include <stdio.h>
int main(int argc, char* argv[])
{
char const* const fileName = argv[1]; /* should check that argc > 1 */
FILE* file = fopen(fileName, "r"); /* should check the result */
char line[256];
while (fgets(line, sizeof(line), file)) {
/* note that fgets don't strip the terminating \n, checking its
presence would allow to handle lines longer that sizeof(line) */
printf("%s", line);
}
/* may check feof here to make a difference between eof and io failure -- network
timeout for instance */
fclose(file);
return 0;
}
파일에서 한 줄을 읽으려면 다음 fgets
함수를 사용해야합니다 . 지정된 파일에서 줄 바꿈 문자 또는 EOF
.
상수 문자열 리터럴 에서 읽기위한 형식 문자열로 sscanf
사용 filename
하므로 코드에서을 사용 하면 전혀 작동하지 않습니다 .line
%s
SEGV의 이유는 .NET에서 가리키는 할당되지 않은 메모리에 쓰기 때문입니다 line
.
개행 \t
대신 탭 과 같은 다른 구분 기호를 다루고 있다고 가정하십시오 \n
.
구분 기호에 대한보다 일반적인 접근 방식은 getc()
한 번에 한 문자를 가져 오는를 사용 하는 것입니다.
를 getc()
반환 int
하므로와 같은지 테스트 할 수 있습니다 EOF
.
둘째, 스택에 최대 문자 를 저장하기 위해 line[BUFFER_MAX_LENGTH]
유형 의 배열 을 정의합니다 ( 종료 문자를 위해 마지막 문자를 저장해야 함 ).char
BUFFER_MAX_LENGTH-1
\0
배열을 사용 하면 힙에서 올바른 길이의 문자 포인터 를 사용 malloc
하고 free
만들 필요가 없습니다 .
#define BUFFER_MAX_LENGTH 1024
int main(int argc, char* argv[])
{
FILE *file = NULL;
char line[BUFFER_MAX_LENGTH];
int tempChar;
unsigned int tempCharIdx = 0U;
if (argc == 2)
file = fopen(argv[1], "r");
else {
fprintf(stderr, "error: wrong number of arguments\n"
"usage: %s textfile\n", argv[0]);
return EXIT_FAILURE;
}
if (!file) {
fprintf(stderr, "error: could not open textfile: %s\n", argv[1]);
return EXIT_FAILURE;
}
/* get a character from the file pointer */
while(tempChar = fgetc(file))
{
/* avoid buffer overflow error */
if (tempCharIdx == BUFFER_MAX_LENGTH) {
fprintf(stderr, "error: line is too long. increase BUFFER_MAX_LENGTH.\n");
return EXIT_FAILURE;
}
/* test character value */
if (tempChar == EOF) {
line[tempCharIdx] = '\0';
fprintf(stdout, "%s\n", line);
break;
}
else if (tempChar == '\n') {
line[tempCharIdx] = '\0';
tempCharIdx = 0U;
fprintf(stdout, "%s\n", line);
continue;
}
else
line[tempCharIdx++] = (char)tempChar;
}
return EXIT_SUCCESS;
}
If you must use a char *
, then you can still use this code, but you strdup()
the line[]
array, once it is filled up with a line's worth of input. You must free
this duplicated string once you're done with it, or you'll get a memory leak:
#define BUFFER_MAX_LENGTH 1024
int main(int argc, char* argv[])
{
FILE *file = NULL;
char line[BUFFER_MAX_LENGTH];
int tempChar;
unsigned int tempCharIdx = 0U;
char *dynamicLine = NULL;
if (argc == 2)
file = fopen(argv[1], "r");
else {
fprintf(stderr, "error: wrong number of arguments\n"
"usage: %s textfile\n", argv[0]);
return EXIT_FAILURE;
}
if (!file) {
fprintf(stderr, "error: could not open textfile: %s\n", argv[1]);
return EXIT_FAILURE;
}
while(tempChar = fgetc(file))
{
/* avoid buffer overflow error */
if (tempCharIdx == BUFFER_MAX_LENGTH) {
fprintf(stderr, "error: line is too long. increase BUFFER_MAX_LENGTH.\n");
return EXIT_FAILURE;
}
/* test character value */
if (tempChar == EOF) {
line[tempCharIdx] = '\0';
dynamicLine = strdup(line);
fprintf(stdout, "%s\n", dynamicLine);
free(dynamicLine);
dynamicLine = NULL;
break;
}
else if (tempChar == '\n') {
line[tempCharIdx] = '\0';
tempCharIdx = 0U;
dynamicLine = strdup(line);
fprintf(stdout, "%s\n", dynamicLine);
free(dynamicLine);
dynamicLine = NULL;
continue;
}
else
line[tempCharIdx++] = (char)tempChar;
}
return EXIT_SUCCESS;
}
In addition to the other answers, on a recent C library (Posix 2008 compliant), you could use getline. See this answer (to a related question).
ReferenceURL : https://stackoverflow.com/questions/9206091/going-through-a-text-file-line-by-line-in-c
'program story' 카테고리의 다른 글
시간당 DateTime 수에 따른 SQL Server 그룹? (0) | 2021.01.10 |
---|---|
IIS 관리자에서 SSL 인증서 적용 및 "다른 프로세스에서 사용 중이므로 프로세스에서 파일에 액세스 할 수 없습니다."오류 (0) | 2021.01.10 |
emerge 대신 git mergetool로 kdiff3을 구성하는 방법은 무엇입니까? (0) | 2021.01.10 |
WiX를 사용하여 CustomActionData를 CustomAction에 전달하는 방법은 무엇입니까? (0) | 2021.01.10 |
.isin ( 'X')가 아닌 행 제거 (0) | 2021.01.10 |