Вход на сайт
CStdioFile - bad ptr (Visual C++)
11.05.06 15:35
Есть два файла. один читается (modeRead), в другой (modeCreate|modeWrite) пишется информация. Вс╦ функционирует одновременно в одном цикле.
После завершения цикла. вызывается метод Close для обоих файлов. Тот файл, который читался, закрывается без ошибок.
Файл в который вс╦ писалось не закрывается.
CXX0030: Error: expression cannot be evaluated char
и -
_tmpfname 0x00000000 <Bad Ptr> char *
для чтения и записи использую функции ReadString() и WriteString()
Как можно решить эту проблему?
После завершения цикла. вызывается метод Close для обоих файлов. Тот файл, который читался, закрывается без ошибок.
Файл в который вс╦ писалось не закрывается.
CXX0030: Error: expression cannot be evaluated char
и -
_tmpfname 0x00000000 <Bad Ptr> char *
для чтения и записи использую функции ReadString() и WriteString()
Как можно решить эту проблему?
NEW 11.05.06 16:40
в ответ voxel3d 11.05.06 15:59
ULONGLONG ulPosition,i;
int n;
CString csStr,csStr1,csHelp,csLineNumber;
CStdioFile ifile(csFileName,CFile::modeRead);
csOutfile = pGlobals->m_ggsTargetDir+"\\"+PathFindFileName(csFileName);
if (!PathFileExists(pGlobals->m_ggsTargetDir))
{
csOutfile = pGlobals->m_ggsProjectPath;
if(!csOutfile.IsEmpty())
{
// csOutfile can contain
// - a directory-path
// - a file-path
// -> check it
if(GetFileAttributes(csOutfile) & FILE_ATTRIBUTE_DIRECTORY)
csOutfile += "\\" + csFileName;
else
{
char szPath[_MAX_PATH],
szDrive[_MAX_DRIVE],
szDir[_MAX_DIR],
szFName[_MAX_FNAME],
szExt[_MAX_EXT];
_splitpath(csOutfile, szDrive, szDir, szFName, szExt);
_makepath(szPath, szDrive, szDir, "", "");
csOutfile = szPath;
}
// (2) Set/create default output directory (...\OUTPUT\SRC)
csOutfile += "OUTPUT\\INSTRPRO";
if(!::CreateDirectory(csOutfile, NULL))
{
// directory already exists
}
csOutfile += "\\" + csFileName;
}
else
{
//error message
//pGlobals->Error
return 0;
}
}
CStdioFile ofile(csOutfile,CFile::modeCreate|CFile::modeWrite);
i=n=0;
ulPosition=ifile.Seek(0,ifile.end);
ifile.SeekToBegin();
ifile.ReadString(csStr);
csStr.Trim();
while (i<ulPosition)
{
if (csStr.Left(1)!="#" || csStr.Left(1)=="")
{
do
{
ofile.WriteString(csStr+"\n");
ifile.ReadString(csStr);
csStr.Trim();
i++;
}while (csStr.Left(1)!="#" && i<ulPosition);
}
if (csStr.Left(1)=="#")
{
csHelp="";
n=0;
csHelp=UntilCharacterStr(csStr,' ',n); //check directive "if...",...,"endif"
if (csHelp=="#if" ||
csHelp=="#ifdef" ||
csHelp=="#ifndef" ||
csHelp=="#endif" ||
csHelp=="#error" ||
csHelp=="#elif" ||
csHelp=="#else")
{
char temp=0;
csLineNumber=LineNumber(CString(ltoa(i,&temp,10)),2);
ofile.WriteString(csLineNumber+csStr+"\n");
ifile.ReadString(csStr);
csStr.Trim();
i++;
} //end of check directive "if...",...,"endif"
do
{
ifile.ReadString(csStr1);
csStr1.Trim();
if (csStr1.Right(1)!="\\") break;
i++;
}while (csStr.Left(1)!="#" && (csStr.Left(1)!="/" || csStr.Left(1)!="*" ));
char temp=0;csLineNumber=LineNumber(CString(ltoa(i,&temp,10)),2);
csStr1=CheckStr(csStr);
if (m_bError!=TRUE)ofile.WriteString(csLineNumber+(LPCTSTR)csStr1);
}
ifile.ReadString(csStr);
csStr.Trim();
i++;
}
ifile.Close();
ofile.Close();
if (m_bError==TRUE) ofile.Remove(csOutfile);
int n;
CString csStr,csStr1,csHelp,csLineNumber;
CStdioFile ifile(csFileName,CFile::modeRead);
csOutfile = pGlobals->m_ggsTargetDir+"\\"+PathFindFileName(csFileName);
if (!PathFileExists(pGlobals->m_ggsTargetDir))
{
csOutfile = pGlobals->m_ggsProjectPath;
if(!csOutfile.IsEmpty())
{
// csOutfile can contain
// - a directory-path
// - a file-path
// -> check it
if(GetFileAttributes(csOutfile) & FILE_ATTRIBUTE_DIRECTORY)
csOutfile += "\\" + csFileName;
else
{
char szPath[_MAX_PATH],
szDrive[_MAX_DRIVE],
szDir[_MAX_DIR],
szFName[_MAX_FNAME],
szExt[_MAX_EXT];
_splitpath(csOutfile, szDrive, szDir, szFName, szExt);
_makepath(szPath, szDrive, szDir, "", "");
csOutfile = szPath;
}
// (2) Set/create default output directory (...\OUTPUT\SRC)
csOutfile += "OUTPUT\\INSTRPRO";
if(!::CreateDirectory(csOutfile, NULL))
{
// directory already exists
}
csOutfile += "\\" + csFileName;
}
else
{
//error message
//pGlobals->Error
return 0;
}
}
CStdioFile ofile(csOutfile,CFile::modeCreate|CFile::modeWrite);
i=n=0;
ulPosition=ifile.Seek(0,ifile.end);
ifile.SeekToBegin();
ifile.ReadString(csStr);
csStr.Trim();
while (i<ulPosition)
{
if (csStr.Left(1)!="#" || csStr.Left(1)=="")
{
do
{
ofile.WriteString(csStr+"\n");
ifile.ReadString(csStr);
csStr.Trim();
i++;
}while (csStr.Left(1)!="#" && i<ulPosition);
}
if (csStr.Left(1)=="#")
{
csHelp="";
n=0;
csHelp=UntilCharacterStr(csStr,' ',n); //check directive "if...",...,"endif"
if (csHelp=="#if" ||
csHelp=="#ifdef" ||
csHelp=="#ifndef" ||
csHelp=="#endif" ||
csHelp=="#error" ||
csHelp=="#elif" ||
csHelp=="#else")
{
char temp=0;
csLineNumber=LineNumber(CString(ltoa(i,&temp,10)),2);
ofile.WriteString(csLineNumber+csStr+"\n");
ifile.ReadString(csStr);
csStr.Trim();
i++;
} //end of check directive "if...",...,"endif"
do
{
ifile.ReadString(csStr1);
csStr1.Trim();
if (csStr1.Right(1)!="\\") break;
i++;
}while (csStr.Left(1)!="#" && (csStr.Left(1)!="/" || csStr.Left(1)!="*" ));
char temp=0;csLineNumber=LineNumber(CString(ltoa(i,&temp,10)),2);
csStr1=CheckStr(csStr);
if (m_bError!=TRUE)ofile.WriteString(csLineNumber+(LPCTSTR)csStr1);
}
ifile.ReadString(csStr);
csStr.Trim();
i++;
}
ifile.Close();
ofile.Close();
if (m_bError==TRUE) ofile.Remove(csOutfile);
NEW 11.05.06 17:23
в ответ JacksonB 11.05.06 16:40
Меня слегка заколдобило от кода, но может оно так и надо, не програмер я. Это известное МФЦ?
Так вот. Судя по всему проблема не закрытии файла. Где-то что-то не того типа стоит. Скорее всего, даже при открытии файла.
---
Лицо фиpмы - это жопа секpетаpши
Так вот. Судя по всему проблема не закрытии файла. Где-то что-то не того типа стоит. Скорее всего, даже при открытии файла.
---
Лицо фиpмы - это жопа секpетаpши
NEW 12.05.06 09:44
в ответ scorpi_ 11.05.06 23:48
Знаете, вы меня поражаете. Я пишу на с++ только 2 месяца. И вот эти восклицания
>Ужас. Уволил бы за такой код. Сразу и навсегда.
меня обижают. Нельзя так сходу говорить. Если вы такой опытный в программировании, то почему бы не сказать как лучше писать. Вроде бы для этого существует форум, задавать вопросы и получать ответы по возможности, а не простите за выражение "обсирать" тех у кого что-то не получается или кто "ужасно пишет".
>Ужас. Уволил бы за такой код. Сразу и навсегда.
меня обижают. Нельзя так сходу говорить. Если вы такой опытный в программировании, то почему бы не сказать как лучше писать. Вроде бы для этого существует форум, задавать вопросы и получать ответы по возможности, а не простите за выражение "обсирать" тех у кого что-то не получается или кто "ужасно пишет".
NEW 12.05.06 10:14
в ответ Murr 12.05.06 02:40
у меня была одна похожая ошибка с <bat ptr>. я присваивал в структурной переменной значение и параллельно присваивал значение массиву.
example:
struct.b=csValue; array[i-1]=TRUE;
получалось что i была равна 0 минус 1 получалось -1 //моя ошибка не досмотрел :)
и переменная struct.b получала другой адрес и в дальнейшем <bat pointer>.
Может где-то скрылась подобная ошибка?
example:
struct.b=csValue; array[i-1]=TRUE;
получалось что i была равна 0 минус 1 получалось -1 //моя ошибка не досмотрел :)
и переменная struct.b получала другой адрес и в дальнейшем <bat pointer>.
Может где-то скрылась подобная ошибка?
NEW 12.05.06 10:18
в ответ scorpi_ 12.05.06 10:11
Кстати я в данный момент пишу на ANSI C, но код выглядит вполне прилично.
------
Так ведь без разницы на чем писать. В pure С чуток больше - на один массив указателей - для эмуляции полиморфизма... Знаком с одним из американских продуктов, написанных целиком на pure C и не имеющим больших проблем - ребята там даже эмуляцию интерфейсов имеют...
------
Так ведь без разницы на чем писать. В pure С чуток больше - на один массив указателей - для эмуляции полиморфизма... Знаком с одним из американских продуктов, написанных целиком на pure C и не имеющим больших проблем - ребята там даже эмуляцию интерфейсов имеют...

NEW 12.05.06 10:26
в ответ JacksonB 11.05.06 16:40
Я не буду комментировать весь кусок, только то, что мне ударило в глаза с первого взгляда, так сказать.
1. Метод ReadString возвращает FALSE, если конец файла. Читать строку из файла нужно только ОДИН раз - в while. Я думаю, все твои неприятности идут оттуда.
2. ulPosition - это не число строк, как ты думаешь, а число байтов - длина файла.
1. Метод ReadString возвращает FALSE, если конец файла. Читать строку из файла нужно только ОДИН раз - в while. Я думаю, все твои неприятности идут оттуда.
2. ulPosition - это не число строк, как ты думаешь, а число байтов - длина файла.
NEW 12.05.06 11:06
в ответ scorpi_ 12.05.06 10:22
Как раз эмуляция полиморфизма и позволяет обрабатывать подобные неприятности - при ошибке дергается обработчик со стандартным смещением и подменяет следующий вызов на процедуру обработки ошибки. За смещениями, разумеется, надо следить, но это легче, чем писать иффы...

NEW 12.05.06 11:56
в ответ scorpi_ 12.05.06 11:16
Нет конечно. Это же не стандартная методика. Делал когда-то для себя - вроде работало. Там ничего сложно - по потребностям - делаешь массив - одна строка - одна эмулируемая функция. По желанию делаешь два-четыре+ укзателя - (пролог), функция, эпилог, (ошибка) - по ситуации - вызываешь что надо косвенно...

NEW 12.05.06 12:01
в ответ JacksonB 12.05.06 11:48
только я не нашёл другой возможности считать строки в файле.
------
Забудь, и лучше всего - навсегда, что файл может состоять из строк. В любом случае автомат анализатора получит всего два дополнительных состояния... в большинстве случаев они будут еще и неразличимы...
P.S. Не тушуйся - тут _пальцы_...
------
Забудь, и лучше всего - навсегда, что файл может состоять из строк. В любом случае автомат анализатора получит всего два дополнительных состояния... в большинстве случаев они будут еще и неразличимы...

P.S. Не тушуйся - тут _пальцы_...



NEW 12.05.06 12:03
Ну ладно, объясняю по буквам...
0. Чтобы получить помощь на форуме программистов необходимо как минимум подать проблему в удобоваримом виде.
0.1 Описать решаемую проблему. Вполне возможно, что ты подошёл к решению проблемы неправильно (и здесь как раз тот самый случай).
0.2 Сведи проблему к минимальной компилируемой программе.
0.3 Представь данную программу в удобно читаемом, отформатированном виде.
Я не зря задал вопрос о источнике обучения. Ибо так писать не стоит.
1. Используй стандартные классы std::string, std::ifstream, std::ofstream.
2. Структурируй программу. Функция должна в идеале содержать не более 7 логических элементов, иначе она неудобоварима.
3. И наконец о самой проблеме. Если тебе нужен scanner - возьми Lex. Так как пытаешься это сделать ты их не пишут, их пишут как конечные автоматы, иначе ты очень быстро запутаешься в дебрях разветвлений.
ЗЫ Какие у тебя Vorkenntnisse? Знания языков (английский, немецкий)? Могу посоветовать, бросить книжку...
в ответ JacksonB 12.05.06 09:44
В ответ на:
меня обижают. Нельзя так сходу говорить.
меня обижают. Нельзя так сходу говорить.
Ну ладно, объясняю по буквам...
0. Чтобы получить помощь на форуме программистов необходимо как минимум подать проблему в удобоваримом виде.
0.1 Описать решаемую проблему. Вполне возможно, что ты подошёл к решению проблемы неправильно (и здесь как раз тот самый случай).
0.2 Сведи проблему к минимальной компилируемой программе.
0.3 Представь данную программу в удобно читаемом, отформатированном виде.
Я не зря задал вопрос о источнике обучения. Ибо так писать не стоит.
1. Используй стандартные классы std::string, std::ifstream, std::ofstream.
2. Структурируй программу. Функция должна в идеале содержать не более 7 логических элементов, иначе она неудобоварима.
3. И наконец о самой проблеме. Если тебе нужен scanner - возьми Lex. Так как пытаешься это сделать ты их не пишут, их пишут как конечные автоматы, иначе ты очень быстро запутаешься в дебрях разветвлений.
ЗЫ Какие у тебя Vorkenntnisse? Знания языков (английский, немецкий)? Могу посоветовать, бросить книжку...
NEW 12.05.06 12:29
в ответ Simple 12.05.06 12:20
Возьми исходники RatC и посмотри как и что там раскидано. Если исходники не найдешь - там синтасический анализатор реализован в виде рекурсивного спуска - когда что-то в нем дохнет - найти концы просто не реально - около 20К if-while-do...
В свое время он меня настолько утомил, что пришлось его заменить... таблицей и полустраницей кода...


NEW 12.05.06 12:57
Боже упаси! Я как раз советую начинать с "Accelerated C++" Кёнига, потому что он с самого начала приучает использовать std::string вместо char* и std::vector вместо масивов...
На английском могу её кинуть. У Анатоликса наверно лучше начать с Липпмана.
в ответ Russman 12.05.06 12:35
В ответ на:
Может с Kernigan & Ritchie? :-)
Может с Kernigan & Ritchie? :-)
Боже упаси! Я как раз советую начинать с "Accelerated C++" Кёнига, потому что он с самого начала приучает использовать std::string вместо char* и std::vector вместо масивов...
На английском могу её кинуть. У Анатоликса наверно лучше начать с Липпмана.
NEW 12.05.06 13:15
> Мне трудно понять в данный момент разницу между C++ и Visual С++.
> меня обижают. Нельзя так сходу говорить. Если вы такой опытный в программировании, то почему бы не сказать как лучше писать.
Он тебе сказал не к тому, что Visual C++ это не C++. Ты пишешь код "в духе" C и вдобавок у тебя каша полная, тебе при желании нельзя помочь.
Давай попробую основу показать для копирования контента с возможностью его преобразования, может быть, оно тебе полезно будет.
Проверку файла назначения соответственно делай до, нефиг всё в одну кучу лепить, а парсинг строк в funct::operator() дёргай, возвращаемое значение будет записываться в результирующий файл.
2аll: критика приветствуется...
> меня обижают. Нельзя так сходу говорить. Если вы такой опытный в программировании, то почему бы не сказать как лучше писать.
Он тебе сказал не к тому, что Visual C++ это не C++. Ты пишешь код "в духе" C и вдобавок у тебя каша полная, тебе при желании нельзя помочь.
Давай попробую основу показать для копирования контента с возможностью его преобразования, может быть, оно тебе полезно будет.
В ответ на:
using namespace std;
class line : public string {};
istream& operator>>(istream& i, line& s)
{
s.clear();
getline(i, s);
s.push_back('\n');
return i;
}
struct funct : unary_function<const line&, line>
{
line operator()(const line& l) const
{
return l;
}
};
void foo()
{
ifstream is("source.txt");
istream_iterator<line> ii(is), eof;
ofstream os("dest.txt");
ostream_iterator<line> oo(os);
transform(ii, eof, oo, funct());
}
Проверку файла назначения соответственно делай до, нефиг всё в одну кучу лепить, а парсинг строк в funct::operator() дёргай, возвращаемое значение будет записываться в результирующий файл.
2аll: критика приветствуется...
Dropbox - средство синхронизации и бэкапа файлов.
NEW 12.05.06 13:22
> зы Но обычно, если указатель нулевой, ошибка другая...
Угу, я пургу прогнал. У него где-то "портится" хэндл на файл в ofile, где - убей, понять не могу. Потенциальных мест дофига, где именно, хрен поймёшь в таком коде.
Угу, я пургу прогнал. У него где-то "портится" хэндл на файл в ofile, где - убей, понять не могу. Потенциальных мест дофига, где именно, хрен поймёшь в таком коде.
Dropbox - средство синхронизации и бэкапа файлов.
NEW 12.05.06 14:37
Просто скопировать файл можно и так:
#include <string>
#include <fstream>
#include <iterator>
#include <algorithm>
using namespace std;
int main()
{
copy( istream_iterator<string>( ifstream("source.txt") ),
istream_iterator<string>(),
ostream_iterator<string>( ofstream("dest.txt"), "\n") );
}
а вот это ближе к проблеме ОП:
смотри update ниже - ошибка с tok_end
NEW 12.05.06 15:00
в ответ scorpi_ 12.05.06 14:37
int main()
{
transform( istream_iterator<line>( ifstream("source.txt") ),
istream_iterator<line>(),
ostream_iterator<string>( ofstream("dest.txt"), "\n" ),
funct() );
}
-----
Надо было довести до совершенства:
int main()
{
TMyTransformer.Transform( istream_iterator<line>( ifstream("source.txt") ),
istream_iterator<line>(),
ostream_iterator<string>( ofstream("dest.txt"), "\n" ),
funct() );
}
где Transform - статический метод TMyTransformer...
А то опять недоученным останется...
{
transform( istream_iterator<line>( ifstream("source.txt") ),
istream_iterator<line>(),
ostream_iterator<string>( ofstream("dest.txt"), "\n" ),
funct() );
}
-----
Надо было довести до совершенства:
int main()
{
TMyTransformer.Transform( istream_iterator<line>( ifstream("source.txt") ),
istream_iterator<line>(),
ostream_iterator<string>( ofstream("dest.txt"), "\n" ),
funct() );
}
где Transform - статический метод TMyTransformer...
А то опять недоученным останется...


NEW 12.05.06 15:05
в ответ scorpi_ 12.05.06 14:37
Сорри, проверить не могу, посему, возможно, глупые вопросы.
перед выходом, надо добавить '\n' к строке?
первый аргумет, это аргумент, последний -- возвращаемое значение. Аргументу -- констанстность и ссылочность. У тебя ниже operator() объявлен. Вероятно, в объявлении структуры ты местами перепутал string с line -ом?
В ответ на:
istream& operator>>( istream& i, line& s )
{
s.clear();
getline( i, s );
return i;
}
перед выходом, надо добавить '\n' к строке?
В ответ на:
struct funct : unary_function< string, line >
...
string operator()( line l )
первый аргумет, это аргумент, последний -- возвращаемое значение. Аргументу -- констанстность и ссылочность. У тебя ниже operator() объявлен. Вероятно, в объявлении структуры ты местами перепутал string с line -ом?
Dropbox - средство синхронизации и бэкапа файлов.
NEW 12.05.06 15:10
в ответ scorpi_ 12.05.06 14:37
В ответ на:
#include <string>
#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <functional>
#include <sstream>
#include <set>
using namespace std;
const char* ar_tokens[] = { "#if", "#ifdef", "#ifndef", "#endif", "#error", "#elif", "#else", "#include" };
string to_string( int i )
{
stringstream ss;
ss << i;
return ss.str();
}
class line : public string {};
istream& operator>>( istream& i, line& s )
{
s.clear();
getline( i, s );
return i;
}
struct funct : unary_function< const line&, string >
{
set< string > tokens_;
int line_number_;
string token_;
bool is_preprocessor_token( const string& l )
{
string::size_type tok_begin = l.find_first_not_of( " \t" );
if ( string::npos != tok_begin && l[tok_begin] == '#' )
{
string::size_type tok_end = l.find_first_of( " \t" );
token_ = ( string::npos == tok_end ) ?
l.substr( tok_begin ) : l.substr( tok_begin, tok_end - tok_begin );
if ( tokens_.find( token_ ) != tokens_.end() )
return true;
}
return false;
}
public:
funct() : line_number_(0)
{
for( int i = 0; i < sizeof( ar_tokens ) / sizeof( char* ); ++i )
tokens_.insert( ar_tokens[ i ] );
}
string operator()( const line& l )
{
++line_number_;
return is_preprocessor_token( l ) ? to_string( line_number_ ) : l;
}
};
int main()
{
transform( istream_iterator<line>( ifstream("source.txt") ),
istream_iterator<line>(),
ostream_iterator<string>( ofstream("dest.txt"), "\n" ),
funct() );
}
NEW 12.05.06 15:47
в ответ voxel3d 12.05.06 15:35
Не, один раз. Иначе и строки бы не считались. Его можно впрочем и явно создать, я так делаю, когда мне данные из него позже нужны:
В ответ на:
funct f( someargs );
transform( istream_iterator<line>( ifstream("source.txt") ),
istream_iterator<line>(),
ostream_iterator<string>( ofstream("dest.txt"), "\n" ),
f );
// use f
NEW 12.05.06 15:54
в ответ Simple 12.05.06 15:35
Я даже когда MFC использую пишу почти всё на стандартном С++. Даже такую вот фигню писал, чтобы держать члены диалога в стрингах:
В ответ на:
void AFXAPI DDX_String( CDataExchange* pDX, int nIDC, std::string& value )
{
HWND hWndCtrl = pDX->PrepareEditCtrl( nIDC );
if ( pDX->m_bSaveAndValidate )
{
std::vector< char > v( ::GetWindowTextLength( hWndCtrl ) + 1, 0 );
::GetWindowText( hWndCtrl, &v[0], v.size() );
value = std::string( &v[0], v.size() - 1 );
}
else
SetWindowText( hWndCtrl, value.c_str() );
}
NEW 12.05.06 16:02
в ответ Simple 12.05.06 15:53
transform тут не прич╦м. transform это движение source, dest итераторов, запись в объект, на который указывает dest итератор разультата вызова operator() функтора, которому переда╦тся объект, на который указывает source итератор.
Dropbox - средство синхронизации и бэкапа файлов.
NEW 12.05.06 16:19
в ответ Simple 12.05.06 16:08
Какой именно объект?
Я сказал о том, как работает функция transform. Там никакие объекты не создаются. Вернее, созда╦тся объект, как оказалось один, но компилятором, неявно. Короче, мой вопрос сводится к тому, что, каково время жизни объекта, при следующем вызове: SomeClass(); где SomeClass -- имя класса.

Я сказал о том, как работает функция transform. Там никакие объекты не создаются. Вернее, созда╦тся объект, как оказалось один, но компилятором, неявно. Короче, мой вопрос сводится к тому, что, каково время жизни объекта, при следующем вызове: SomeClass(); где SomeClass -- имя класса.
Dropbox - средство синхронизации и бэкапа файлов.
NEW 12.05.06 16:24
в ответ voxel3d 12.05.06 16:19
При хорошем компайлере - ноль - вызов конструктора будет исключен(?) при оптимизации.
При среднем - быдет вызван конструктор и следом - деструктор.
При плохом, а большинство делает именно так - деструктор будет вызван при выходе из области определения.
Если надо точнее - надо рыть стандарт и доки на реализацию...
При среднем - быдет вызван конструктор и следом - деструктор.
При плохом, а большинство делает именно так - деструктор будет вызван при выходе из области определения.
Если надо точнее - надо рыть стандарт и доки на реализацию...
NEW 12.05.06 16:28
То бишь funct() создаётся до исполнения transform, и живёт до её конца.
в ответ voxel3d 12.05.06 15:51
В ответ на:
1.9 (8)
Once the execution of a function begins, no expressions from the calling function are evaluated until execution of the called function has completed.
1.9 (17)
When calling a function (whether or not the function is inline), there is a sequence point after the evaluation of all function arguments (if any) which takes place before execution of any expressions or statements in the function body.
5.2.2 (4)
When a function is called, each parameter (8.3.5) shall be initialized (8.5, 12.8, 12.1) with its corresponding argument. ... The lifetime of a parameter ends when the function in which it is defined returns.
5.2.2 (8)
The order of evaluation of arguments is unspecified. All side effects of argument expression evaluations take effect before the function is entered. The order of evaluation of the postfix expression and the argument expression list is unspecified.
1.9 (8)
Once the execution of a function begins, no expressions from the calling function are evaluated until execution of the called function has completed.
1.9 (17)
When calling a function (whether or not the function is inline), there is a sequence point after the evaluation of all function arguments (if any) which takes place before execution of any expressions or statements in the function body.
5.2.2 (4)
When a function is called, each parameter (8.3.5) shall be initialized (8.5, 12.8, 12.1) with its corresponding argument. ... The lifetime of a parameter ends when the function in which it is defined returns.
5.2.2 (8)
The order of evaluation of arguments is unspecified. All side effects of argument expression evaluations take effect before the function is entered. The order of evaluation of the postfix expression and the argument expression list is unspecified.
То бишь funct() создаётся до исполнения transform, и живёт до её конца.
NEW 12.05.06 16:35
в ответ Simple 12.05.06 16:28
Тут все просто: функция получает копию объекта
------
Это тебе так хочется. Тем не мение - построение объекта и передача объекта в качестве параметра есть несколько разные операции и между ними вполне может произойти куча всякой всячины.. ну и такая малость, как вызов деструктора объекта...
------
Это тебе так хочется. Тем не мение - построение объекта и передача объекта в качестве параметра есть несколько разные операции и между ними вполне может произойти куча всякой всячины.. ну и такая малость, как вызов деструктора объекта...

NEW 12.05.06 16:37
Уговорил - напишу компайлер который не будет создавть эти объекты...
P.S. Разумеется придется изучить стандарт на предмет обязательности создания объектов (т.е. вызовов невиртуальных конструкторов) при отсутствии в теле операций со статическими объектами...

P.S. Разумеется придется изучить стандарт на предмет обязательности создания объектов (т.е. вызовов невиртуальных конструкторов) при отсутствии в теле операций со статическими объектами...
NEW 12.05.06 16:44
В данном случае я спрашивал о времени жизни временного объекта при вызове SomeClass(); Мурр дал ответ, что хороший компайлер не станет вызывать конструктор SomeClass::SomeClass(), после чего я спросил: "даже если там будет код в конструкторе"? Спросив я сразу понял глупость вопроса -- если будет код, то компайлер его вырезать не станет, посколько никаких ответов не было ещё, я просто удалил вопрос, чтобы не было лишнего мусора.
Dropbox - средство синхронизации и бэкапа файлов.
NEW 12.05.06 16:46
в ответ Simple 12.05.06 11:50
Я разобрался с bad ptr
CString(ltoa(k,&temp,10)) проблема была тут. как только я ltoa требует к переменной k тип long там раньше стояла переменная i типа ULONGLONG
видать что-то в памяти происходило, но как только я изменил это заработало.
Вопрос. Как я могут узнать конец файла или нет в классе CFile
пример:
CStdio ifile ;
while (!iflie.eof)
{
}
так было бы прекрасно. но я там не наш╦л такого метода (eof).
CString(ltoa(k,&temp,10)) проблема была тут. как только я ltoa требует к переменной k тип long там раньше стояла переменная i типа ULONGLONG
видать что-то в памяти происходило, но как только я изменил это заработало.
Вопрос. Как я могут узнать конец файла или нет в классе CFile
пример:
CStdio ifile ;
while (!iflie.eof)
{
}
так было бы прекрасно. но я там не наш╦л такого метода (eof).
NEW 12.05.06 16:56
в ответ voxel3d 12.05.06 16:44
если будет код, то компайлер его вырезать не станет
------
Компайлер не может удалить вызов если есть побочный эффект от вызова или он не в состоянии определить наличие такого эффект - изменяется статический член, конструктор виртуальный, информация по базовому классу недоступна...
Реально же отследить эти условия не слишком просто, особенно если есть крутая иерархия и потому _большинство_ компайлеров будет строить вызов конструктора и вызов деструктора. Когда именно будет вызван последний - сразу или при выходе из области определения - не важно, кроме ситуаций с ошибками.
------
Компайлер не может удалить вызов если есть побочный эффект от вызова или он не в состоянии определить наличие такого эффект - изменяется статический член, конструктор виртуальный, информация по базовому классу недоступна...
Реально же отследить эти условия не слишком просто, особенно если есть крутая иерархия и потому _большинство_ компайлеров будет строить вызов конструктора и вызов деструктора. Когда именно будет вызван последний - сразу или при выходе из области определения - не важно, кроме ситуаций с ошибками.
NEW 12.05.06 17:02
в ответ JacksonB 12.05.06 16:46
> CString(ltoa(k,&temp,10)) проблема была тут. как только я ltoa требует к переменной k тип long там раньше стояла переменная i типа ULONGLONG
2all: что-то я чисто теоретически даже не могу понять, как из-за этого могли проблемы данные быть. У кого-нибудь есть идеи?
2all: что-то я чисто теоретически даже не могу понять, как из-за этого могли проблемы данные быть. У кого-нибудь есть идеи?
Dropbox - средство синхронизации и бэкапа файлов.
NEW 12.05.06 17:21
в ответ scorpi_ 12.05.06 17:16
Я тоже удивился, но решил что человеку воспитаному на РАПИРА и вынесшему основные знания по информатике из школы, лучше не выступать. Мало ли как там людей на факультетах информатики и кибернетики учат.
---
Сделать из мухи слона нетрудно, труднее его прокормить. (2:5030/67)
---
Сделать из мухи слона нетрудно, труднее его прокормить. (2:5030/67)
NEW 12.05.06 17:27
в ответ voxel3d 12.05.06 17:22
В ответ на:
char * ltoa ( long value, char * buffer, int radix );
Convert long integer value to string.
Converts a long integer value to a null-terminated string using the specified radix and stores the result in the given buffer. If radix is 10 and value is negative the string is preceded by the minus sign (-). With any other radix, value is always considered unsigned. buffer should be large enough to contain any possible value: (sizeof(long)*8+1) for radix=2.
NEW 12.05.06 17:42
При том, что если не знать в какую сторону растёт стек и как размещаются переменные, можно представить, например, такую картину:
var_1, var_2, ..., var_n
где var_1 это ofile (где хэндл портился), а var_2 это тот самый char, в который буфер пытались записать; при росте стека вверх и таком размещении, испортить ofile не удастся.
p.s. (слева меньшие адреса, справа большие)
var_1, var_2, ..., var_n
где var_1 это ofile (где хэндл портился), а var_2 это тот самый char, в который буфер пытались записать; при росте стека вверх и таком размещении, испортить ofile не удастся.
p.s. (слева меньшие адреса, справа большие)
Dropbox - средство синхронизации и бэкапа файлов.
NEW 12.05.06 17:53
в ответ scorpi_ 12.05.06 17:38
Локальные переменные в порядке декларации, порядок аргументов не определён.
------
Да, внесли в стандарт порядок создания переменных... По моему - зря. Для скалярных можно выделять непрерывный блок, а не скалярные - определять в конструкторе...
Порядков - два. слева направо, справо налево. Какой именно используется надо смотреть в доках на компайлер... в стандарте вроде не было ограничений.
------
Да, внесли в стандарт порядок создания переменных... По моему - зря. Для скалярных можно выделять непрерывный блок, а не скалярные - определять в конструкторе...
Порядков - два. слева направо, справо налево. Какой именно используется надо смотреть в доках на компайлер... в стандарте вроде не было ограничений.
NEW 15.05.06 14:58
в ответ scorpi_ 12.05.06 17:29
Программа читает файл по строчно, делает грамматический разбор каждой строчки. строка должна начинаться с объявления #define #ifdef ... и тому подобное, только тогда происходит разбор строки.
Со String действительно удобно работать, только возникают проблемы с е╦ конвертацией в char или long или int.
есть функция strtol(char *c, char **endptr,int i)
мне нужно преобразовать HEX число в Decimal. вот и проблема конвертации CString в Char.
не подскажите как можно сконвертировать или есть ли другие функции?
с iostream тоже много неопредел╦нности. как читает она строчку с файла, откуда я могу знать размер строчки заранее и т.д.
Со String действительно удобно работать, только возникают проблемы с е╦ конвертацией в char или long или int.
есть функция strtol(char *c, char **endptr,int i)
мне нужно преобразовать HEX число в Decimal. вот и проблема конвертации CString в Char.
не подскажите как можно сконвертировать или есть ли другие функции?
с iostream тоже много неопредел╦нности. как читает она строчку с файла, откуда я могу знать размер строчки заранее и т.д.
NEW 15.05.06 15:16
в ответ JacksonB 15.05.06 14:58
> с iostream тоже много неопредел╦нности. как читает она строчку с файла
Ты имеешь в виду istream. Показали же: наследуешь класс от std::string и перегружаешь глобальный оператор >>. Про размер строки мысль не понял. Зачем его надо знать заранее?
Ты имеешь в виду istream. Показали же: наследуешь класс от std::string и перегружаешь глобальный оператор >>. Про размер строки мысль не понял. Зачем его надо знать заранее?
Dropbox - средство синхронизации и бэкапа файлов.
NEW 15.05.06 15:19
в ответ JacksonB 15.05.06 14:58
http://www.cppreference.com/
> Со String действительно удобно работать, только возникают проблемы с еe конвертацией в char или long или int.
есть функция strtol(char *c, char **endptr,int i)
c_str, atol, atoi
> не нужно преобразовать HEX число в Decimal. вот и проблема конвертации CString в Char.
Нет проблем, ставь в atoi сразу чар с хекс значением.
> как читает она строчку с файла, откуда я могу знать размер строчки заранее и т.д.
В этом-то и прелесть. Он просто читает строчку, неважно какой она длины.
---
Ничто так не согревает душу, как холодное пиво
> Со String действительно удобно работать, только возникают проблемы с еe конвертацией в char или long или int.
есть функция strtol(char *c, char **endptr,int i)
c_str, atol, atoi
> не нужно преобразовать HEX число в Decimal. вот и проблема конвертации CString в Char.
Нет проблем, ставь в atoi сразу чар с хекс значением.
> как читает она строчку с файла, откуда я могу знать размер строчки заранее и т.д.
В этом-то и прелесть. Он просто читает строчку, неважно какой она длины.
---
Ничто так не согревает душу, как холодное пиво
NEW 15.05.06 15:34
Это мы и сами видим. Вопрос в другом: препроцессор-директивы - это всё что нужно анализировать, или ещё что-то? Каким образом происходит анализ строки?
Забудь про CString, работай с std::string. Конвертирование ты мог видеть в моей программе:
А есои писать в стрим, то вообще ничего не нужно конвертировать.
getline( stream, string ) читает строку в string, и тебе совершенно не нужно при этом заморачиваться длинной строки.
в ответ JacksonB 15.05.06 14:58
В ответ на:
Программа читает файл по строчно, делает грамматический разбор каждой строчки. строка должна начинаться с объявления #define #ifdef ... и тому подобное, только тогда происходит разбор строки.
Программа читает файл по строчно, делает грамматический разбор каждой строчки. строка должна начинаться с объявления #define #ifdef ... и тому подобное, только тогда происходит разбор строки.
Это мы и сами видим. Вопрос в другом: препроцессор-директивы - это всё что нужно анализировать, или ещё что-то? Каким образом происходит анализ строки?
В ответ на:
Со String действительно удобно работать, только возникают проблемы с её конвертацией в char или long или int. есть функция strtol(char *c, char **endptr,int i) мне нужно преобразовать HEX число в Decimal. вот и проблема конвертации CString в Char.
Со String действительно удобно работать, только возникают проблемы с её конвертацией в char или long или int. есть функция strtol(char *c, char **endptr,int i) мне нужно преобразовать HEX число в Decimal. вот и проблема конвертации CString в Char.
Забудь про CString, работай с std::string. Конвертирование ты мог видеть в моей программе:
В ответ на:
template< class T >
std::string to_string( T t)
{
stringstream ss;
ss << t;
return ss.str();
}
А есои писать в стрим, то вообще ничего не нужно конвертировать.
В ответ на:
с iostream тоже много неопределённости. как читает она строчку с файла, откуда я могу знать размер строчки заранее и т.д.
с iostream тоже много неопределённости. как читает она строчку с файла, откуда я могу знать размер строчки заранее и т.д.
getline( stream, string ) читает строку в string, и тебе совершенно не нужно при этом заморачиваться длинной строки.
NEW 15.05.06 16:01
в ответ scorpi_ 15.05.06 15:34
после директив ид╦т имя объекта и далее ид╦т название аттрибута объекта затем значение аттрибута объекта и т.д. взависимости сколько аттрибутов у объекта.
CString CheckStr(cstr) делает этот разбор,проверка существует ли объект в системе, и возвращает назад строку, которую нужно писать в выходной файл.
CString CheckStr(cstr) делает этот разбор,проверка существует ли объект в системе, и возвращает назад строку, которую нужно писать в выходной файл.
NEW 15.05.06 16:13
Я собственно почему спрашиваю? Я пытаюсь понять, насколько сложен анализ строки. Дело в том, что начиная с определённой сложности нет смысла делать это в лоб - лучше применить известные алгоритмы и программы из Compilerbau (Lex, Yacc и тому подобные). В противном же случае можно просто взять мою программу, заменить тело функции string funct::operator()( const line& l ) на CheckStr и готово. Ты можешь запостить здесь CheckStr, или это коммерческая тайна?
в ответ JacksonB 15.05.06 16:01
В ответ на:
после директив идёт имя объекта и далее идёт название аттрибута объекта затем значение аттрибута объекта и т.д. взависимости сколько аттрибутов у объекта.
после директив идёт имя объекта и далее идёт название аттрибута объекта затем значение аттрибута объекта и т.д. взависимости сколько аттрибутов у объекта.
Я собственно почему спрашиваю? Я пытаюсь понять, насколько сложен анализ строки. Дело в том, что начиная с определённой сложности нет смысла делать это в лоб - лучше применить известные алгоритмы и программы из Compilerbau (Lex, Yacc и тому подобные). В противном же случае можно просто взять мою программу, заменить тело функции string funct::operator()( const line& l ) на CheckStr и готово. Ты можешь запостить здесь CheckStr, или это коммерческая тайна?

NEW 15.05.06 16:21
в ответ scorpi_ 15.05.06 16:13
нет не тайна. Надеюсь я потом не увижу "Ужас."..... и так далее.
ULONGLONG ulLength;
int i,iPosAttr,n;
bool b;
CString csHelp,csHelp2,csHelp3,vs;
ulLength=csString.GetLength();
iPosAttr=i=0;
EmptyAttr();
while (i<=ulLength)
{
csHelp="";
b=FALSE;
while (!(csString.Mid(i,1)==" " || csString.Mid(i,1)=="\t")) //until first blank
{
csHelp+=csString.Mid(i,1);
i++;
if (i>ulLength) break;
if (CheckDefine(csHelp) && iPosAttr==0) {iPosAttr++;b=TRUE;}
if (csString.Mid(i-1,1)=="#")
while ((csString.Mid(i,1)==" " || csString.Mid(i,1)=="\t") && iPosAttr==0)
{
i=UntilSymbol(csString,i);
b=TRUE;
}
while ((csString.Mid(i,1)==" " || csString.Mid(i,1)=="\t") && iPosAttr>=2)
{
if (i>ulLength) break;
i=UntilSymbol(csString,i);
if (csString.Mid(i+1,1)=="=") {csHelp+=csString.Mid(i+1,1);i+=2;}
csHelp2=csString.Mid(i,3);
if ((CheckAttributen(csString.Mid(i,3),"",1)!="ERROR" || CheckAttributen(csString.Mid(i,2),"",1)!="ERROR") && csString.Mid(3,1)!="=")
{
iPosAttr++;i--;break;
}else csHelp+=" ";
b=TRUE;
}
}
if (!b)iPosAttr++;
if (CheckDefine(csHelp) && iPosAttr==1)
m_Attr.csDeclaration=csHelp;
if (iPosAttr==2)
{
m_Attr.csName=csHelp;
}
if (iPosAttr>=3)
{ csHelp2=csHelp3="";
n=0;
while (csHelp.Mid(n,1)!="=" && n<=csHelp.GetLength()) //get name of attribute
{
csHelp2+=csHelp.Mid(n,1);
n++;
}
n++;
while (n<=csHelp.GetLength()) //get value of attribute
{
csHelp3+=csHelp.Mid(n,1);
n++;
}
CheckAttributen(csHelp2.Trim(),csHelp3.Trim(),1);
}
i=UntilSymbol(csString,i);
}
return CheckObjects();
ULONGLONG ulLength;
int i,iPosAttr,n;
bool b;
CString csHelp,csHelp2,csHelp3,vs;
ulLength=csString.GetLength();
iPosAttr=i=0;
EmptyAttr();
while (i<=ulLength)
{
csHelp="";
b=FALSE;
while (!(csString.Mid(i,1)==" " || csString.Mid(i,1)=="\t")) //until first blank
{
csHelp+=csString.Mid(i,1);
i++;
if (i>ulLength) break;
if (CheckDefine(csHelp) && iPosAttr==0) {iPosAttr++;b=TRUE;}
if (csString.Mid(i-1,1)=="#")
while ((csString.Mid(i,1)==" " || csString.Mid(i,1)=="\t") && iPosAttr==0)
{
i=UntilSymbol(csString,i);
b=TRUE;
}
while ((csString.Mid(i,1)==" " || csString.Mid(i,1)=="\t") && iPosAttr>=2)
{
if (i>ulLength) break;
i=UntilSymbol(csString,i);
if (csString.Mid(i+1,1)=="=") {csHelp+=csString.Mid(i+1,1);i+=2;}
csHelp2=csString.Mid(i,3);
if ((CheckAttributen(csString.Mid(i,3),"",1)!="ERROR" || CheckAttributen(csString.Mid(i,2),"",1)!="ERROR") && csString.Mid(3,1)!="=")
{
iPosAttr++;i--;break;
}else csHelp+=" ";
b=TRUE;
}
}
if (!b)iPosAttr++;
if (CheckDefine(csHelp) && iPosAttr==1)
m_Attr.csDeclaration=csHelp;
if (iPosAttr==2)
{
m_Attr.csName=csHelp;
}
if (iPosAttr>=3)
{ csHelp2=csHelp3="";
n=0;
while (csHelp.Mid(n,1)!="=" && n<=csHelp.GetLength()) //get name of attribute
{
csHelp2+=csHelp.Mid(n,1);
n++;
}
n++;
while (n<=csHelp.GetLength()) //get value of attribute
{
csHelp3+=csHelp.Mid(n,1);
n++;
}
CheckAttributen(csHelp2.Trim(),csHelp3.Trim(),1);
}
i=UntilSymbol(csString,i);
}
return CheckObjects();
NEW 15.05.06 16:51
в ответ JacksonB 15.05.06 16:21
А куда ты денешься - "Ужас, нах...", разумеется. Есть такая штучка как регехп - как раз для этого думана - режет текст на заданные части, если это возможно. Вместо этого коде будет одна (или несколько) строка шаблона парсинга и одна строка вызова...
P.S. Переставая работать с глобальными переменными.

P.S. Переставая работать с глобальными переменными.
NEW 15.05.06 17:17
Заменяй на нормальный XML -проще жить будет. У меня в текущем проекте такая же подсистема - собираются куски с разных мест с заменой атрибутов на переопределенные. По объему - не на много больше приведенного кода, но много понятнее...

NEW 15.05.06 17:21
в ответ JacksonB 15.05.06 16:39
Если у тебя парсинг строк только такого вида, без пробелов вокруг знака "="
то наверняка есть стандартная процедура, нарезающая строку на куски с разделителем ПРОБЕЛ и после этого - еще раз каждый из кусков по знаку "="... смотри в сторону split(?)
то наверняка есть стандартная процедура, нарезающая строку на куски с разделителем ПРОБЕЛ и после этого - еще раз каждый из кусков по знаку "="... смотри в сторону split(?)

NEW 15.05.06 17:44
в ответ Murr 15.05.06 17:21
в том то весь и прикол. вс╦ было бы проще, если бы не было zwischenraumов между всем.
в задании и стоит что между равно могут быть пробелы. ещ╦ может быть такая фишка, что type=unsignet int
между unsigned и int тоже пробел.
я раньше в дельфи писал.
там мне не приходилось заботить о том, что что-то на что-то в стеке писаться будет.
тут надо прям за всем смотреть.
в задании и стоит что между равно могут быть пробелы. ещ╦ может быть такая фишка, что type=unsignet int
между unsigned и int тоже пробел.
я раньше в дельфи писал.
там мне не приходилось заботить о том, что что-то на что-то в стеке писаться будет.
тут надо прям за всем смотреть.
NEW 15.05.06 20:17
в ответ JacksonB 15.05.06 17:44
У меня босс обычно спрашивает - сколько времени займет вариант с пробелами и сколько - без. Меньше без - пишем в доку, что пробелов там не должно быть, и все должно быть отквочено... В любом случае нет смысла разбирать строку посимвольно...
И подумай серьезно об XML - для этих вещей он проще...
И подумай серьезно об XML - для этих вещей он проще...
NEW 16.05.06 00:46
в ответ JacksonB 15.05.06 16:39
Есть ещё такая прикольная штучка как Spirit http://spirit.sourceforge.net/distrib/spirit_1_8_3/libs/spirit/index.html
Вот примерчик для затравки:
Ausgabe:
Object name: Name
Object attribute name: type
Object attribute value: int
Object attribute name: xdm
Object attribute value: 3
Object attribute name: ydm
Object attribute value: 2
Object attribute name: model
Object attribute value: KMO_2
Object name: Name2
Object attribute name: type
Object attribute value: uint
Вот примерчик для затравки:
В ответ на:
#include <boost/spirit/core.hpp>
#include <iostream>
#include <string>
#include <map>
using namespace std;
using namespace boost::spirit;
void set_object_name( char const* first, char const* last )
{
cout << "Object name: " << string(first, last) << endl;
}
void set_object_attr_name( char const* first, char const* last )
{
cout << "Object attribute name: " << string(first, last) << endl;
}
void set_object_attr_value( char const* first, char const* last )
{
cout << "Object attribute value: " << string(first, last) << endl;
}
struct object_parser : public grammar< object_parser >
{
template <typename ScannerT>
struct definition
{
definition( object_parser const& /*self*/ )
{
expression = str_p( "#define" )
>> word [ &set_object_name ]
>> *attr
;
attr = word [ &set_object_attr_name ]
>> '='
>> word [ &set_object_attr_value ]
;
word = lexeme_d[ +(alnum_p | '_') ];
}
rule<ScannerT> expression, attr, attr_value, word;
rule<ScannerT> const& start() const { return expression; }
};
};
int main()
{
object_parser parser;
parse_info<> info = parse( "#define Name type=int xdm=3 ydm=2 model=KMO_2", parser, space_p );
if ( ! info.full )
cout << "Parsing failed at: " << info.stop << endl;
info = parse( "#define Name2 type=uint", parser, space_p );
if ( ! info.full )
cout << "Parsing failed at: " << info.stop << endl;
}
Ausgabe:
Object name: Name
Object attribute name: type
Object attribute value: int
Object attribute name: xdm
Object attribute value: 3
Object attribute name: ydm
Object attribute value: 2
Object attribute name: model
Object attribute value: KMO_2
Object name: Name2
Object attribute name: type
Object attribute value: uint