program story

C에서 한 줄씩 텍스트 파일을 살펴보기

inputbox 2021. 1. 10. 17:13
반응형

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]유형 의 배열 정의합니다 ( 종료 문자를 위해 마지막 문자를 저장해야 함 ).charBUFFER_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

반응형