数週間前、私は(私はそれらを使用するために使用されていないよ)浮かぶ、初めてダブルスを使用していた、と私は持っています比較オペランドにいくつかの問題があります。その型に値を代入しようとすると問題が発生しましたが、解決しました...「のunsigned long int型」と「unsigned long型long int型」割り当て問題
今日、私はC++でライブラリを作成していますが、エラーが見つかりました...よく...奇妙な?またはちょうど私の愚かな考えですか?
ini::ini(const char * path, bool _autoflush_ /*= false*/) {
/* Storing file name ... */
f_name = new char[strlen(path)+1];
strcpy(f_name, path);
/* Storing autoflush ... */
autoflush = _autoflush_;
/* First step: getting file size */
/* Open the file in read/append mode */
FILE * fd = fopen(path, "r");
/* On non-valid descriptor, goto next step directly */
if(fd == NULL) f_size = 1; goto allocbuffer;
/* Seek to the end */
fseek(fd, 0, SEEK_END);
/* Get file size */
f_size = (unsigned long int)ftell(fd) + 1;
/* Second step: allocating memory for the buffer */ allocbuffer:
cout << endl << endl << endl << endl << "Wanting " << sizeof(char)*f_size << " bytes of memory!" << endl << endl << endl << endl;
/* Allocate buffer-space */
buffer = (char*)malloc(sizeof(char)*f_size);
if(buffer == NULL) {
errord = (char*)malloc(strlen(INI_ERROR_NOT_ENOUGH_MEMORY) + 1);
strcpy(errord, INI_ERROR_NOT_ENOUGH_MEMORY);
cout << endl << endl << endl << endl << "Last error: \"" << errord << "\"." << endl << endl << endl << endl;
return;
}
/* Initialize and fill it with null bytes */
memset(buffer, 0, f_size);
/* Goto next step */
if(fd == NULL) goto endconstruct;
/* Third step: storing in the buffer */ loadbuffer:
/* Rewind file descriptor */
rewind(fd);
/* Read from file */
if(fread(buffer, 1, f_size, fd) != f_size) {
errord = (char*)malloc(strlen(INI_ERROR_NOT_READED) + 1);
strcpy(errord, INI_ERROR_NOT_READED);
cout << endl << endl << endl << endl << "Last error: \"" << errord << "\"." << endl << endl << endl << endl;
cout << endl << endl << endl << endl << "BYTES OF FILE: \"" << f_size << "\"." << endl << endl << endl << endl;
}
/* Close file descriptor */
fclose(fd);
/* Get number of lines */
f_line = strnum(buffer, "\n") + 1;
/* End building of object */
endconstruct:
/* Print out what is stored in the buffer NOW */
cout << endl << endl << endl << endl << "Buffer is:" << endl << buffer << endl << endl << endl << endl;
return;
}
おそらくのiniライブラリがすでに作成されている、と私よりもはるかに優れ:
これはコードです。しかし、私はCからC++を学び始めています。興味深いものを使って練習したいと思います。私はそれがここでそれを貼り付けることが必要だが、ここにある場合、私は知らない、クラス宣言を逃した:いくつかの「テスト」の後
/** @def INI_ERROR_NOT_READED
@brief <em>Not readed as many bytes as required</em>
*/
#define INI_ERROR_NOT_READED "Not readed as many bytes as required"
/** @def INI_ERROR_NOT_ENOUGH_MEMORY
@brief <em>There is not enough memory</em>
*/
#define INI_ERROR_NOT_ENOUGH_MEMORY "There is not enough memory"
/** @class ini
@brief Class to describe <em>ini</em> files.
It describes an ini file. All the file is readed and loaded
in memory, for faster access. This class is the
improved & C++ version of the old, monstruous
functions defined in the old, monstruous IO Utilities
Library. Writting functions use dynamic memory reallocation
and file flush to the filesystem.
*/
class ini {
public:
/** @brief Constructor. Gives initial memory for the buffer and loads all the file in that buffer.
*
* @param path - Path of the <em>ini</em> file to open.
* @param _autoflush_ - Whether to auto-flush changes to hard disk or not.
* If you don't set it to any value, <em>false</em> is taked as default
* value and you have to flush changes manually using member function flush().
* Setting it to <em>true</em> may make it less efficient, so be careful
* if you're going to make a lot of changes in the <em>ini</em> file.
*/
ini (const char * path, bool _autoflush_ = false);
/** @brief Destructor. Frees the memory pointed by <em>buffer</em> and destroys the #ini object.
*
* It's very important to free the memory buffer, to avoid memory corruptions.
*/
~ini (void);
/** @brief Gets last error stored in private member <em>errord</em>.
*
* @return Last error-descriptor as string.
*/
char * geterror (void);
/** @brief Flush changes made in the buffer to the hard disk.
*
* You can do it manually or set auto-flushing by the second argument of
* ini::ini().
*
* @par Example of usage:
* @code
* ini inid("myini.ini");
* // make changes
* inid.flush();
* @endcode
*/
void flush (void);
/** @brief Flush changes made in the buffer to *another* file the hard disk.
*
* Using this function instead of normal flush(void), you are able to
* save the buffer to another #ini file that is not the original one.
*
* @par Example of usage:
* @code
* ini inid("myini.ini");
* // make changes
* inid.flush("myini.backup.ini");
* @endcode
*/
void flush (const char * path);
/** @brief Checks if a section exists.
*
* @param tsection - The name of the section to check, without the braces.
*
* @return #true if the section exists; #false if not.
*/
bool sectExists (const char * tsection);
/** @brief Gets the line in that a section starts.
*
* @param tsection - The name of the section to check, without the braces.
*
* @return The line in that the section starts; -1 if not-founded section.
* Keep in mind that the first line is 1, the second, 2,...
*/
int sectStart (const char * tsection);
/** @brief Gets the line in that a section ends.
*
* @param tsection - The name of the section to check, without the braces.
*
* @return The line in that the section ends; -1 if not-founded section.
* Keep in mind that the first line is 1, the second, 2,...
*/
int sectStop (const char * tsection);
/** @brief Checks if a key exists.
*
* @param tsection - The name of the section to check, without the braces.
* If the key is outside any section (if it's a #KWOS), then <em>tsection</em>
* should be #KWOS.
* @param tkey - The name of the key to check.
*
* @return #true if the key exists in the specified section; #false if not.
*/
int keyExists (const char * tsection, const char * tkey);
/** @brief Reads the value of a key as a string.
*
* @param tsection - The name of the section to read from, without the braces.
* If the key is outside any section (if it's a #KWOS), then <em>tsection</em>
* should be #KWOS.
* @param tkey - The name of the key to read its value.
* @param tval - The default string to return if cannot found the key.
*
* @return The value of the key <em>tkey</em> in section <em>tsection</em>; or
* <em>tval</em> when non-existing key.
*/
char * read (const char * tsection, const char * tkey, const char * tval);
/** @brief Reads the value of a key as an integer value.
*
* @param tsection - The name of the section to read from, without the braces.
* If the key is outside any section (if it's a #KWOS), then <em>tsection</em>
* should be #KWOS.
* @param tkey - The name of the key to read its value.
* @param tval - The default value to return if cannot found the key.
*
* @return The value of the key <em>tkey</em> in section <em>tsection</em>; or
* <em>tval</em> when non-existing key.
*/
long int readi (const char * tsection, const char * tkey, int tval);
bool delKey (const char * tsection, const char * tkey);
bool delSect (const char * tsection);
bool write (const char * tsection, const char * tkey, const char * tval);
bool write (const char * tsection, const char * tkey, int tval);
private:
unsigned long int f_size; /**< File size. */
unsigned int f_line; /**< Number of lines of the <em>ini</em> file. */
char * buffer; /**< Memory buffer to store data. Dynamimcally reallocated. */
char * f_name; /**< File name. */
bool autoflush; /**< Whether to auto-flush to hard disk or not. */
char * errord; /**< Last error stored internally by the functions of the #ini class. */
};
、私は最終的に問題は「F_SIZE」であることを発見しました変数。どうして?わからない。しかし、標準出力に出力すると、非常に大きな数値が表示されます。これは、メモリ割り当て(mallocによる)エラーとファイルからの読み込み(またはmemsetによる初期化)のエラーです。
大変助かります。そして私の誤りを見てもらうためのリンク、参考文献や説明、そして学習を続ける。
ありがとうございます!
P .:私はLinux Debianの "squeeze"、amd64でg ++を使用しています。ファイルがが存在しない
if(fd == NULL) f_size = 1; goto allocbuffer;
場合は、ロジックはまだallocbuffer
にラベルを付けるためにジャンプ:
BTW 'strlen'と' new char [] '? 「malloc」さえ?あなたはまだCで考えていますが、 'std :: string'とprosperを使用しています。 – Kos
しかし、私は 'still' use _const char * _と_char * _...を見たことがあるので、メモリを動的に再割り当てするためには_realloc_バッファ –
コンテナクラスを作成していない場合に、バッファに動的に再割り当てされたメモリが必要なのはなぜですか? – Kos