通过char数组指针返回垃圾值存储结构成员数据

4smxwvx5  于 2021-06-20  发布在  Mysql
关注(0)|答案(3)|浏览(483)

我试图在oled lcd上显示我的数据库数据 MySQL_Connection.h 以及 MySQL_Cursor.hChuckBell .
指向此库的链接是https://github.com/chuckbell/mysql_connector_arduino>
我可以从 mysql database 成功。但是,我希望将数据存储在char数组中,以便以后可以在oled lcd上显示它们。问题是存储的值总是返回垃圾值。我知道这和char数组指针有关,但是在搜索了这么长时间之后,我仍然找不到正确的语法。下面是我的代码片段。
首先设置wifi连接和mysql连接。

  1. # include <MySQL_Connection.h>
  2. # include <MySQL_Cursor.h>
  3. char query[] = "SELECT * FROM test.assetdemo WHERE RFID = \"048EB25A\""; //sql query
  4. char* sqldata[11]; //array of char pointer to store the 11 data in the database
  5. void setup(){
  6. Serial.begin(115200);
  7. internetConnect(ssid,pw); //connect to Wifi
  8. conn.connect(server_addr, 3306, user, password); //connect to mysqldatabase
  9. }

然后开始循环函数来存储和显示数据库数据。

  1. void loop(){
  2. Serial.println("\nRunning SELECT and printing results\n");
  3. MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn); // Initiate the query class instance
  4. cur_mem->execute(query); // Execute the query
  5. row_values *row = NULL; // Read the rows and print them
  6. do {
  7. row = cur_mem->get_next_row();
  8. if (row != NULL) {
  9. for (int f = 0; f < cols->num_fields; f++) {
  10. sqldata[f] = row->values[f];
  11. Serial.print(f);
  12. Serial.print(" ");
  13. Serial.println(sqldata[f]); /*This works*/
  14. }
  15. Serial.println();
  16. }
  17. } while (row != NULL);
  18. Serial.println(sqldata[0]); /*This return garbage value*/
  19. delete cur_mem; // frees up memory used
  20. delay(5000);
  21. }

输出如下图所示单击此处或在下面查看。如您所见,值在 do while 循环。但是,当我退出循环并再次打印值时,它返回垃圾值 . sqldata[0] 假定返回 048EB25A .

  1. Running SELECT and printing results
  2. 0 048EB25A
  3. 1 Blood Pressure Monitor
  4. 2 NA
  5. 3 WelchAllyn 503-0054-03
  6. 4 010720
  7. 5 NA
  8. 6 NA
  9. 7 Blood Pressure Cuff
  10. 8
  11. 9 Yes
  12. 10 1

下面的代码段显示了中的结构声明 MySQL_Cursor.h ```
typedef struct {
char *db;
char *table;
char *name;
} field_struct;

// Structure for storing result set metadata.
typedef struct {
int num_fields; // actual number of fields
field_struct *fields[MAX_FIELDS];
} column_names;

// Structure for storing row data.
typedef struct {
char *values[MAX_FIELDS];
} row_values;

  1. 我的一部分意识到了这一点 `sqldata[f] = row->values[f];` 正在导致垃圾值。该值将更改,因为指针仅指向地址。如何静态存储变量,以便在 `do while` ,该值将持续吗?好心的先生和女士请解释这个秘密。
  2. ps:我对数组和指针感到困惑,当它们涉及结构时更是如此。
b5buobof

b5buobof1#

来自@tk ooi的解决方案是可以的,但是作为对它的改进,我会更安全地使用我们想要存储数据的数组的大小,因此可以不用使用

  1. int numberRows = 11;
  2. char**sqldata = new char*[numberRows];
  3. for(int i = 0; i < numberRows; i++ ) {
  4. sqldata[i] = new char[numberChars];
  5. }
  6. strcpy(sqldata[f], (*row).values[f]);`

最好将char*数组声明为全局数组,但在查询函数内部执行以下操作:

  1. int numberChars = strlen((*row).values[f]);
  2. sqldata[f] = new char[numberChars]; // implies already extra place for null terminator
  3. snprintf(sqldata[f], strlen(sqldata[f]), "%s", (*row).values[f]);`

通过这种方式,我们总是为存储恢复数据的数组指定精确的长度。注意,使用 numberChars 而不是 strlen(sqldata[f]) 将失败,因为需要根据存储在中的类型传递长度 sqldata :对我来说不一样 int 至于 char ...

apeeds0o

apeeds0o2#

解释是在get\u next\u row函数中释放内存https://github.com/chuckbell/mysql_connector_arduino/blob/master/src/mysql_cursor.cpp

  1. /*
  2. get_next_row - Iterator for reading rows from a result set
  3. This method returns an instance of a structure (row_values)
  4. that contains an array of strings representing the row
  5. values returned from the server.
  6. The caller can use the values however needed - by first
  7. converting them to a specific type or as a string.
  8. * /
  9. row_values *MySQL_Cursor::get_next_row() {
  10. int res = 0;
  11. free_row_buffer();
  12. // Read the rows
  13. res = get_row_values();
  14. if (res != MYSQL_EOF_PACKET) {
  15. return &row;
  16. }
  17. return NULL;
  18. }

在第二次尝试获取行空闲时,调用行缓冲区。

展开查看全部
2jcobegt

2jcobegt3#

多亏了@jabberwocky和@rantanpan的建议,我自己也找到了解决办法。他们给了我一个在哪里寻找解决办法的方向。通过编辑 sqldata 如下所示,我能够将字符串而不是指针存储到sqldata中。
重新声明sqldata,如下所示。

  1. char**sqldata = new char*[11]; //to store 11 data for each query executed
  2. for ( int i = 0; i < 11; i++ )
  3. {
  4. sqldata[i] = new char[11];
  5. }

然后更换 sqldata[f] = row->values[f];strcpy(sqldata[f], (*row).values[f]); 现在一切正常。是时候在oled lcd上打印这些废话了。再次感谢各位!

相关问题