|
|
Yes, you are right.
THESE PEOPLE REALLY BOTHER ME!! How can they know what you should do without knowing what you want done?!?!
-- C++ FQA Lite
|
|
|
|
|
This[^] thread might help. It looks as though there are members of the Address struct one called set and it's getting initialized to 0, and another called id and it's getting initialized to the given integer id.
"the debugger doesn't tell me anything because this code compiles just fine" - random QA comment
"Facebook is where you tell lies to your friends. Twitter is where you tell the truth to strangers." - chriselst
|
|
|
|
|
yes,but by the name of function says(database_delete),this function must delete something,and i don't know how it is deleting something
|
|
|
|
|
Just a guess, perhaps set is some kind of flag marking a record as inactive or something, as opposed to actually deleting a record. What a functions name is and what it actually does may be two different things. What's needed here I believe is some useful comments.
"the debugger doesn't tell me anything because this code compiles just fine" - random QA comment
"Facebook is where you tell lies to your friends. Twitter is where you tell the truth to strangers." - chriselst
|
|
|
|
|
can i give you the entire code?maybe you will find my answer
|
|
|
|
|
This ties into the code you posted below. Specifically, it's related to this method:
void Database_set(struct Connection *conn, int id, const char *name, const char *email)
{
struct Address *addr = &conn->db->rows[id];
if(addr->set) die("Already set, delete it first");
addr->set = 1; Basically, it looks like it's controlling whether or not you've already set the value in this row - so, to set a value here, you would call Database_delete first, which changes the value in id from 1 to 0, which means that the rest of Database_set can continue.
|
|
|
|
|
i understand now,thank you very much!
|
|
|
|
|
You're welcome.
|
|
|
|
|
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#define MAX_DATA 512
#define MAX_ROWS 100
struct Address {
int id;
int set;
char name[MAX_DATA];
char email[MAX_DATA];
};
struct Database {
struct Address rows[MAX_ROWS];
};
struct Connection {
FILE *file;
struct Database *db;
};
void die(const char *message)
{
if(errno) {
perror(message);
} else {
printf("ERROR: %s\n", message);
}
exit(1);
}
void Address_print(struct Address *addr)
{
printf("%d %s %s\n",
addr->id, addr->name, addr->email);
}
void Database_load(struct Connection *conn)
{
int rc = fread(conn->db, sizeof(struct Database), 1, conn->file);
if(rc != 1) die("Failed to load database.");
}
struct Connection *Database_open(const char *filename, char mode)
{
struct Connection *conn = malloc(sizeof(struct Connection));
if(!conn) die("Memory error");
conn->db = malloc(sizeof(struct Database));
if(!conn->db) die("Memory error");
if(mode == 'c') {
conn->file = fopen(filename, "w");
} else {
conn->file = fopen(filename, "r+");
if(conn->file) {
Database_load(conn);
}
}
if(!conn->file) die("Failed to open the file");
return conn;
}
void Database_close(struct Connection *conn)
{
if(conn) {
if(conn->file) fclose(conn->file);
if(conn->db) free(conn->db);
free(conn);
}
}
void Database_write(struct Connection *conn)
{
rewind(conn->file);
int rc = fwrite(conn->db, sizeof(struct Database), 1, conn->file);
if(rc != 1) die("Failed to write database.");
rc = fflush(conn->file);
if(rc == -1) die("Cannot flush database.");
}
void Database_create(struct Connection *conn)
{
int i = 0;
for(i = 0; i < MAX_ROWS; i++) {
// make a prototype to initialize it
struct Address addr = {.id = i, .set = 0};
// then just assign it
conn->db->rows[i] = addr;
}
}
void Database_set(struct Connection *conn, int id, const char *name, const char *email)
{
struct Address *addr = &conn->db->rows[id];
if(addr->set) die("Already set, delete it first");
addr->set = 1;
// WARNING: bug, read the "How To Break It" and fix this
char *res = strncpy(addr->name, name, MAX_DATA);
// demonstrate the strncpy bug
if(!res) die("Name copy failed");
res = strncpy(addr->email, email, MAX_DATA);
if(!res) die("Email copy failed");
}
void Database_get(struct Connection *conn, int id)
{
struct Address *addr = &conn->db->rows[id];
if(addr->set) {
Address_print(addr);
} else {
die("ID is not set");
}
}
void Database_delete(struct Connection *conn, int id)
{
struct Address addr = {.id = id, .set = 0};
conn->db->rows[id] = addr;
}
void Database_list(struct Connection *conn)
{
int i = 0;
struct Database *db = conn->db;
for(i = 0; i < MAX_ROWS; i++) {
struct Address *cur = &db->rows[i];
if(cur->set) {
Address_print(cur);
}
}
}
int main(int argc, char *argv[])
{
if(argc < 3) die("USAGE: ex17 <dbfile> <action> [action params]");
char *filename = argv[1];
char action = argv[2][0];
struct Connection *conn = Database_open(filename, action);
int id = 0;
if(argc > 3) id = atoi(argv[3]);
if(id >= MAX_ROWS) die("There's not that many records.");
switch(action) {
case 'c':
Database_create(conn);
Database_write(conn);
break;
case 'g':
if(argc != 4) die("Need an id to get");
Database_get(conn, id);
break;
case 's':
if(argc != 6) die("Need id, name, email to set");
Database_set(conn, id, argv[4], argv[5]);
Database_write(conn);
break;
case 'd':
if(argc != 4) die("Need id to delete");
Database_delete(conn, id);
Database_write(conn);
break;
case 'l':
Database_list(conn);
break;
default:
die("Invalid action, only: c=create, g=get, s=set, d=del, l=list");
}
Database_close(conn);
return 0;
}
|
|
|
|
|
Alex Sturza wrote: Database_close(conn);
return 0;
} Are you sure that is your question?
|
|
|
|
|
my bad,sry about you wasted time to read my code )
|
|
|
|
|
Just try reading things a bit before posting here. Your other question (in the C# forum) is similar.
|
|
|
|
|
Can you not search this code yourself? Database_close() is called right before main() returns.
In the future, please post only relevant code snippets.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
omg,sry about that badd miss,and thanks anyway!
|
|
|
|
|
Hi,
Is there any way to convert WMI Win32_OperatingSystem InstallDate to mm/dd/yyyy format in C++. I have seen there is a class defined in C# for the same. But I didn't find anything in C++.
When I run WMI query "Select InstallDate from Win32_Operating system", I get : 20120714160600.000000+330 as the result.
I want to convert this to some readable format e:g: dd/mm/yyyy format with time also.
Anybody have any idea about this.?
Regards,
Mbatra
|
|
|
|
|
|
I am trying to enable an application for unicode.
//char c_buffer[ARRAY];
TCHAR c_buffer[ARRAY];
above are the changes I made into code.
Which breaks at this code in the .cpp file
sprintf(c_buffer, "%d", pb->i_id);
abc.cpp: error C2664: 'sprintf': cannot convert parameter 1 from 'TCHAR *[1024]' to 'char *'
Why so ?
I have added TCHAR.h and strsafe.h
|
|
|
|
|
Use wsprintf -
wsprintf(c_buffer, _T("%d"), pb->i_id);
«_Superman_»
I love work. It gives me something to do between weekends.
Microsoft MVP (Visual C++) (October 2009 - September 2013) Polymorphism in C
|
|
|
|
|
Worked ! great... thanks
|
|
|
|
|
Hello superman...just trying my luck by asking this to you...
problem piece of code - if(Function(parm1, parm2, parm3)==0){
error - cannot convert parameter 3 from 'char [1024]' to 'wchar_t *'
Function is expecting wchar_t but its getting char[1024] from some where.
I changed the function signature to accept wchar_t type in header file.
objective is to make the whole code UNICODE enabled. I have added all the tchar.h, wchar.h fiels
param 3 has been defined (modified) as wchar_t in all the connected files too.
I cant debug yet. Pls help how can i get rid of this error.
I am working in vs2010.I counter checked it about five times and gave the search in solution to find if parm3 is still 'char' somewhere else.
I am seriously doubting typecasting the wchar_t parm3[] before passing it function i think.
I went to function declaration and changed it to char* to wchar_t* too. I doubt that might not be straight forward. there should be some changes.
|
|
|
|
|
To support UNICODE, you need to use wchar_t instead of char .
You also need to use the string functions that work on wchar_t like wcslen , wcscat etc.
While defining string literals use the L prefix - L"Hello World"
If you have a string that is already encoded as ASCII, you need to convert it to UNICODE.
Simply typecasting will not work.
You can use the MultiByteToWideChar[^] API to do the conversion.
«_Superman_»
I love work. It gives me something to do between weekends.
Microsoft MVP (Visual C++) (October 2009 - September 2013) Polymorphism in C
|
|
|
|
|
|
However, the swprintf function, which is a VC++ library function is the correct one to use.
The wsprintf function is part of some windows API, and does not support all the formatting options. For example wsprintf does not support the "*" width specification.
Thanks !
|
|
|
|
|
If you are using TCHAR to define your data then you must use the routines with the _st prefix as described in http://msdn.microsoft.com/en-us/library/ybk95axf.aspx[^]/ This allows the compiler to generate code for ASCII or Unicode depending on your project settings. If your program is only ever going to handle Unicode character data then you should use WCHAR and the PW prefixed pointers.
|
|
|
|
|