C에서 텍스트 파일 한 줄씩 살펴보기
나는 CIS 수업을 위해 작은 연습을 하고 있는데 C가 파일에서 읽을 때 사용하는 방법에 매우 혼란스러워.내가 정말 해야 할 일은 한 줄 한 줄씩 파일 한 줄을 읽고 각 줄에서 수집된 정보를 이용하여 몇 가지 조작을 하는 것이다.나는 getline method 등을 사용해 보았지만 운이 없었다.내 코드는 현재 다음과 같다.
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 nobb인데 내가 놓친 큰 그림이 있는지 궁금해서 그래.고마워요.
몇 줄에 문제가 너무 많아.난 아마 몇 가지를 잊어버렸을 것이다.
- argv[0]는 프로그램 이름이며 첫 번째 인수가 아니다.
- 변수를 읽으려면 변수의 메모리를 할당해야 함
- 실패하기 전까지 IO 함수를 반복하지 않고, 실패의 원인을 결정하는 역할을 한다.
- 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의 이유는 다음이 가리키는 할당되지 않은 메모리에 쓰기 때문이다.line
.
다른 답변 외에도 최근 C 라이브러리(Posix 2008 준수)에서 getline을 사용할 수 있다.이 답변(관련 질문에 대한 대답)을 참조하십시오.
예를 들어, 다른 구분 기호를 다루고 있다고 가정해 보십시오.\t
a 대신 tab\n
뉴라인으로 하다
구분자에 대한 보다 일반적인 접근방식은 한 번에 한 문자를 잡는 의 사용이다.
참고:getc()
a를 반환하다.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;
}
만약 당신이 a를 사용해야 하char *
, 그러면 여전히, 하지만 이 코드를 사용할 수 있다.strdup()
그line[]
정열은, 한번 입력 라인의 가치로 가득차 있다.당신은 해야 한다.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;
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;
}
참조URL:https://stackoverflow.com/questions/9206091/going-through-a-text-file-line-by-line-in-c
'Programing' 카테고리의 다른 글
vue-roouter를 사용할 때 페이지 제목을 변경하는 방법 (0) | 2022.05.17 |
---|---|
키가 상승했고 VueJs에Autocomplete으로 찾고 있다. (0) | 2022.05.17 |
nuxtjs로 하위 상태를 매핑하는 방법 (0) | 2022.05.17 |
Vuejs가 캐싱에 대한 계산된 속성의 저하를 어떻게 아는가? (0) | 2022.05.17 |
프로덕션에서 웹 팩 빌드 파일을 제공하기 위해 ngnix를 사용하는 방법 (0) | 2022.05.17 |