programing

C에서 파일 문자를 한 문자씩 읽는 중

sourcetip 2023. 7. 31. 22:21
반응형

C에서 파일 문자를 한 문자씩 읽는 중

C에서 BF 통역기를 쓰고 있는데 파일을 읽는 중에 문제가 생겼습니다.사용한 적이 있습니다.scanf첫 번째 문자열을 읽으려면 BF 코드에 공백이나 주석을 사용할 수 없습니다.

지금 여기 제가 가진 것이 있습니다.

char *readFile(char *fileName)
{
  FILE *file;
  char *code = malloc(1000 * sizeof(char));
  file = fopen(fileName, "r");
  do 
  {
    *code++ = (char)fgetc(file);

  } while(*code != EOF);
  return code;
}

파일의 다음 문자를 코드 포인터에 할당하는 방법에 문제가 발생한다는 것을 알고 있지만 그게 무엇인지 잘 모르겠습니다.
제 포인터 지식이 부족해서 이 연습의 요점입니다.인터프리터는 잘 작동합니다. 포인터를 사용해서요. 파일을 읽는 데 문제가 있을 뿐이에요.

(읽기만 구현할 예정입니다.+-><[].,나중에 파일로, 비록 누군가가 그것을 할 수 있는 좋은 방법이 있다면, 당신이 나에게 알려주면 좋을 것입니다!)

코드에 여러 가지 문제가 있습니다.

char *readFile(char *fileName)
{
    FILE *file;
    char *code = malloc(1000 * sizeof(char));
    file = fopen(fileName, "r");
    do 
    {
      *code++ = (char)fgetc(file);

    } while(*code != EOF);
    return code;
}
  1. 파일이 1,000바이트보다 크면 어떻게 됩니까?
  2. 당신은 증가하고 있습니다.code캐릭터를 읽고 돌아올 때마다code(비록 더 이상 메모리 블록의 첫 번째 바이트를 가리키고 있지 않지만) 호출자에게 되돌아갑니다.malloc).
  3. 당신은 그 결과를 캐스팅하고 있습니다.fgetc(file)로.char다음을 확인해야 합니다.EOF에 결과를 내기 전에char.

에서 반환된 원래 포인터를 유지하는 것이 중요합니다.malloc나중에 자유롭게 사용할 수 있도록 합니다.파일 크기를 무시해도 다음과 같은 이점을 얻을 수 있습니다.

char *readFile(char *fileName)
{
    FILE *file = fopen(fileName, "r");
    char *code;
    size_t n = 0;
    int c;

    if (file == NULL)
        return NULL; //could not open file

    code = malloc(1000);

    while ((c = fgetc(file)) != EOF)
    {
        code[n++] = (char) c;
    }

    // don't forget to terminate with the null character
    code[n] = '\0';        

    return code;
}

파일 크기를 제공하는 다양한 시스템 호출이 있습니다. 일반적인 호출은 입니다.

@dreamlax에서 위의 코드를 확장합니다.

char *readFile(char *fileName) {
    FILE *file = fopen(fileName, "r");
    char *code;
    size_t n = 0;
    int c;

    if (file == NULL) return NULL; //could not open file
    fseek(file, 0, SEEK_END);
    long f_size = ftell(file);
    fseek(file, 0, SEEK_SET);
    code = malloc(f_size);

    while ((c = fgetc(file)) != EOF) {
        code[n++] = (char)c;
    }

    code[n] = '\0';        

    return code;
}

이렇게 하면 파일의 길이가 표시되고 한 글자씩 계속 읽게 됩니다.

여기 유효한 브레인퍽 캐릭터를 제외한 모든 것을 무시하는 간단한 방법이 있습니다.

#define BF_VALID "+-><[].,"

if (strchr(BF_VALID, c))
    code[n++] = c;

함수에 대한 각 호출에 대해서도 파일이 열리고 닫히지 않습니다.

내 생각에 가장 중요한 문제는 당신이 점점 더 증가하고 있다는 것입니다.code당신이 무언가를 읽을 때, 그리고 나서 최종 값을 반환합니다.code즉, 포인터를 문자열 으로 반환합니다.당신은 아마도 복사본을 만들고 싶을 것입니다.code루프 앞에서, 대신 그것을 반환합니다.

또한 C 문자열은 null-termination이 필요합니다.다음을 배치해야 합니다.'\0'당신이 읽은 마지막 문자 바로 뒤에.

참고: 다음을 사용할 수 있습니다.fgets()한 번에 전체 대사를 얻는 것.

둘 중 한 명이 속임수를 써야 합니다.

char *readFile(char *fileName)
{
  FILE *file;
  char *code = malloc(1000 * sizeof(char));
  char *p = code;
  file = fopen(fileName, "r");
  do 
  {
    *p++ = (char)fgetc(file);
  } while(*p != EOF);
  *p = '\0';
  return code;
}

char *readFile(char *fileName)
{
  FILE *file;
  int i = 0;
  char *code = malloc(1000 * sizeof(char));
  file = fopen(fileName, "r");
  do 
  {
    code[i++] = (char)fgetc(file);
  } while(code[i-1] != EOF);
  code[i] = '\0'
  return code;
}

다른 포스터에서 지적한 것처럼 파일 크기가 1000자를 초과하지 않도록 해야 합니다.또한 메모리를 사용한 후에는 메모리를 비우는 것을 기억하세요.

여기서 문제는 두 가지입니다.

  • 판독된 값을 확인하기 전에 포인터를 증분합니다.
  • 당신은 그 사실을 무시합니다.fgetc()char int 합니다.

첫 번째는 쉽게 해결할 수 있습니다.

char *orig = code; // the beginning of the array
// ...
do {
  *code = fgetc(file);
} while(*code++ != EOF);
*code = '\0'; // nul-terminate the string
return orig; // don't return a pointer to the end

는 좀 더 문제입니다.fgetcint를 반환하여 다음과 같이 합니다.EOF값은 가능한 문자 값과 구별할 수 있습니다.이 문제를 해결하려면 임시 int를 사용합니다.EOF확인하고 실행/중 대신 일반적인 실행 루프를 사용할 수 있습니다.

언급URL : https://stackoverflow.com/questions/4823177/reading-a-file-character-by-character-in-c

반응형