2016-07-15 4 views
0

최근에 필자는 간단한 텍스트 - 투 - char 문자열 판독기를 만들었지 만 파일의 끝 부분에 이상한 텍스트를 반환하는 것 같습니다.파일 읽기 손상된 파일 끝 반환

그래서 여기에 내가 읽을려고 파일 중 하나입니다 :

#version 330 core 
in vec3 inputColour; 

out vec4 outputColour; 

void main() 
{ 
    outputColour = vec4(inputColour, 1.0f); 
} 

그것은 GLSL로 작성된 OpenGL을 쉐이더 참고로,입니다. 나는 그것을 "읽기"할 때 그러나,이를 반환

Console Output

참고 명령 창 끝의 네 2 문자. 런타임에이 쉐이더를 컴파일하려고하면 원래 텍스트에없는 일부 문자와 함께 오류가 반환됩니다. 나는 breakpoint를 만들고 그것을 더 깊이 들여다 보았다. 나는 기능을 실행하고 텍스트 영상 효과를 개방하고이를 반환

Text Visualiser Image

가 다시, 텍스트, ýýýý의 끝에서 또 다른 4 개 문자가 있습니다.


다음은 텍스트 리더의 코드입니다 :

std::ifstream inputFile("foo.txt", std::ios::in|std::ios::binary|std::ios::ate); 
int inputFileSize; 
char* buffer = ""; 

if (inputFile.is_open()) 
{ 
    inputFile.seekg(0, std::ios::end); //Set the cursor to the end. 
    inputFileSize = (int)inputFile.tellg(); //Set inputFileSize to the position of the cursor. 
    buffer = new char[inputFileSize]; //Create the buffer and set its size to the inputFileSize. 
    inputFile.seekg(0, std::ios::beg); //Move the cursor to the beginning. 
    inputFile.read(buffer, inputFileSize); //Read the file from the beginning. 
    inputFile.close(); //Close the file 
} 

내 생각이 라인 엔딩 잘못 읽을 함께 할 수있는 뭔가가있을 수 있다는 것입니다. 그러나 Notepad ++ 및 내부 Visual Studio 편집기로 작성된 파일을 테스트했으며 두 결과 모두 동일한 결과를 얻었습니다.

"해결 방법"을 찾을 수있었습니다. 즉, 매우 위험한 해법인데, 이것은 아주 나쁜 습관입니다. 기본적으로 [FILEEND]과 읽은 텍스트 파일의 끝을 넣을 수 있습니다. 코드에서 [FILEEND] 또는 전혀 사용할 수 없지만 파일을 올바르게 읽으려면 코드에 [FILEEND]이 필요합니다.

char* fileend = std::strstr(buffer, "[FILEEND]"); //Find [FILEEND]. 
int actualfilelen = fileend != NULL ? std::strlen(buffer) - std::strlen(fileend) : std::strlen(buffer); //Get the length of the main content of txt file. 
//If there is no [FILEEND] then return the size of the buffer without any adjustments. 
char* output = new char[actualfilelen + 1]; //Create new string with the length of the main content of txt file. 
std::strncpy(output, buffer, actualfilelen); //Copy main content of buffer to output. 
output[actualfilelen] = '\0'; //Add escape sequence to end of file. 
delete(buffer); //Deletes the original buffer to free up memory; 

그런 다음 output 변수를 반환합니다. 파일의 마지막에 [FILEEND] 키워드 (?)를 사용하고 싶지 않으므로 즉시 이동성이 떨어지기 때문에. 하나 또는 두 개의 파일 [FILEEND] 함께 괜찮을 수도 있지만 다른 프로젝트에서 사용하려는 파일이 수백 있다면 그들은 모두 [FILEEND] 있습니다.

답변

1

할당 된 이후

또한, 당신은 내가 해결책을 온 delete[] buffer 필요하지만 string.c_str()로 변환 한 후 std::string를 사용하여 포함한다.

std::string LoadFile(const char* FileLocation) 
{ 
    std::ifstream fileStream; 
    std::string fileOutput, currentLine; 
    fileStream.open(FileLocation); 
    if (fileStream.is_open()) 
    { 
     while (!fileStream.eof()) 
     { 
      std::getline(fileStream, currentLine); 
      fileOutput.append(currentLine + "\n"); 
      std::cout << "> " << currentLine << "\n"; 
     } 
    } 

    fileStream.close(); 

    return fileOutput; 
} 

그리고 당신이 LoadFile과 같은 지시어를 수행하여 std::stringconst char* 기반 동등한를 찾을 수있을 것입니다 ("C : \ example.txt") 을.c_str(); 또는 LoadFile(location)을 새 std::string으로 저장하고 그 위에 .c_str()을 사용합니다.

.c_str()은 로컬 변수에 대한 포인터이기 때문에 쉽게 "반환"할 수 없습니다. 함수가 종료되면 해당 변수는 삭제되고 .c_str()은 null 포인터가됩니다. 필자가 선택한 방법은 함수 또는 API 호출이 필요할 때 .c_str()을 사용하는 것입니다. C++에서는 char* 대신에 std::string을 사용할 때 특히 텍스트 기반 파일 및 C++ 표준 라이브러리을 사용할 때 많은 번거 로움을 덜어주는 것으로 보입니다.

1

버퍼가 \0 종료되었는지 확인하지 않았습니다. 그것을 읽은 후에 inputFileSize+1으로 만들고 종료하십시오.

과 같은 기능은 std::strlen(buffer)과 같습니다. 길이를 제공하지 않고 어디서나 사용하려고하면 버퍼 끝을지나 계속 읽습니다. 이 new[]

+0

필자는 다음과 같이 코드를 편집했습니다. http://pastebin.com/rhdEHP7X 런타임 컴파일러가 이제는이 코드를 완벽하게 읽지 만 텍스트 끝에 '.'기호가 있습니다. 텍스트 인코딩을 유니 코드에서 ANSI로 변경하려고 시도했지만 아무 것도하지 않았습니다. 필자는 printf 함수를 대신 사용하려고했지만 똑같은 결과를 보여주었습니다. 나는 버퍼가 길이로 설정되어 있고 더 출력하기 때문에 이것이 어떻게 일어나는지 이해하지 못한다. 예를 들어, 내 파일 중 하나는 130 자입니다. 관리자는'inputFileSize'가 130인지 확인했습니다. 이제 버퍼는 131이어야하지만 그렇지 않습니다. –

+0

쉐이더에서'[FILEEND]'키워드를 삭제하고'[FILEEND]'단축 코드를 제거했습니다. 나는 그것이 다른 배열에 "복사"되고 삭제되지 않는 한, 함수의 출력이므로 버퍼를 삭제할 수 없습니다. –

+0

최소한의 완전한 프로그램을 입력 파일로 게시하십시오. 최소한의 강조. 내가 편집 및 재현하지 않고 gcc 수 있어야합니다. –