2016-07-15 20 views
0

最近、私は一見シンプルなテキストから文字への文字列リーダを構築しましたが、ファイルの終わりに向かって奇妙なテキストを返すようです。だからここファイルの読み込み破損したファイルの終了を返す

は、私が読んしようとしているファイルの一つだ:

#version 330 core 
in vec3 inputColour; 

out vec4 outputColour; 

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

それはFYI、GLSLで書かれたOpenGLのシェーダです。私はそれを「読み取る」しようとすると、しかし、それは、これを返します。

Console Output

は、コマンドウィンドウの最後に4つの2文字に注意してください。実行時にこのシェーダをコンパイルしようとすると、元のテキストにない文字でエラーが返されます。私はブレークポイントを作成し、それをさらに調べました。私は、関数を実行し、テキスト・ビジュアライザを開いて、それがこの返さ:ここでも、他の4つの文字は、テキスト、ýýýýの最後にあります

Text Visualiser Image

を。私の推測では、それが不正に読み取られて行末とは何かを持っているかもしれないということです

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]の1つまたは2つのファイルは問題ありませんが、別のプロジェクトで使用したい何百ものファイルがある場合は、すべてが[FILEEND]です。

答えて

1

で割り当てられたので、

また、あなたがdelete[] bufferに必要私は解決策が出ているが、それはstd::stringを使用して、string.c_str()でそれを変換することを含みます。

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.SQLの")を。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ランタイムコンパイラは今これを完全に読み込みますが、最後にはテキストに '。 'が付きます。テキストのエンコーディングをUnicodeからANSIに変更しようとしましたが、何もしませんでした。代わりにprintf関数を使用しようとしましたが、まったく同じ結果が表示されました。私はバッファが長さに設定され、より多くを出力するので、これがどうなっているのか分かりません。たとえば、私のファイルの1つは130文字です。インスペクタでは、 'inputFileSize'が130であることを確認しました。バッファーは131になるはずですが、そうではありません。 –

+0

シェイダーの '[FILEEND]'キーワードを削除し、 '[FILEEND]'ショートコードを削除しました。私はそれが別の配列に "コピー"され、削除されるはずでない限り、関数の出力であるので、バッファを削除することはできません。 –

+0

最小限の完全なプログラムを入力ファイルで投稿します。最小限の強調。私は編集して再現せずにgccにできるはずです。 –

関連する問題