string::substrの奇妙な動作に出くわしました。通常、私は Eclipse+MinGW でWindows 7でコーディングしますが、 Linux (Ubuntu 12.04) で Eclipse を使用してラップトップで作業しているときに、結果の違いに気付きました。
テキスト行で満たされたvector< string >で作業していました。手順の 1 つは、行から最後の文字を削除することでした。
win7 Eclipse では、次のようにしました。
for( int i = 0; i < (int)vectorOfLines.size(); i++ )
{
vectorOfTrimmedLines.push_back( ((string)vectorOfLines.at(i)).substr(0, ((string)vectorOfLines.at(i)).size()-1) );
}
意図したとおりに機能します(各行から最後の文字を削除します)
しかし、Linux では、このコードはトリムされません。代わりに、次のようにする必要がありました。
// -2 instead -1 character
vectorOfTrimmedLines.push_back( ((string)vectorOfLines.at(i)).substr(0, ((string)vectorOfLines.at(i)).size()-2) );
または別の方法を使用します。
vectorOfTrimmedLines.push_back( ((string)vectorOfLines.at(i)).replace( (((string)vectorOfLines.at(i)).size()-2),1,"",0 ));
もちろん、Linux の方法は Windows では間違った方法で動作します (最後の 2 文字をトリミングするか、最後の前の文字を置き換える)。
問題は、myString.size() が Windows では文字数を返すのに対し、Linux では文字数 + 1 を返すようです。Linux では改行文字がカウントされるのでしょうか?
C++ およびプログラミング全般の初心者として、なぜそうなるのか、プラットフォームに依存しないようにするにはどうすればよいのか疑問に思います。
私が疑問に思っているもう1つのことは、 substrまたはreplaceのどちらの方法が望ましい(より速い)かということです。
編集:文字列を埋めるために使用される方法は、私が書いたこの関数です:
vector< string > ReadFile( string pathToFile )
{
// opening file
ifstream myFile;
myFile.open( pathToFile.c_str() );
// vector of strings that is returned by this function, contains file line by line
vector< string > vectorOfLines;
// check if the file is open and then read file line by line to string element of vector
if( myFile.is_open() )
{
string line; // this will contain the data read from current the file
while( getline( myFile, line ) ) // until last line in file
{
vectorOfLines.push_back( line ); // add current line to new string element in vector
}
myFile.close(); // close the file
}
// if file does not exist
else
{
cerr << "Unable to open file." << endl; // if the file is not open output
//throw;
}
return vectorOfLines; // return vector of lines from file
}