C - 无法将字符串添加到数组
C - Trouble adding string to array
我正在尝试将字符串添加到我的数组的下一个索引,但是我遇到了这个奇怪的问题,当我添加到 1 以外的任何索引时(是的,我从一个索引我的数组,为了简单起见,只是为了匹配项目的实际数量,对不起!)。本质上,如果我 ass 到索引 1,一切都很好,但是当我添加到索引 2 时,索引 1 的值似乎更改为我计划放入索引 2 的值,甚至在我所在的代码行之前将值添加到索引 2。例如:
假设我尝试将 'test1' 添加到我的数组 queuedHashed[100][101] 的索引 1,然后我 运行 打印数组的所有元素,在索引号旁边,我得到:
1: test1
然而,当我将索引 2 处的 'test2' 添加到数组时,我会得到:
1: test2
2: test2
为了解决这个问题,我费了好几个小时,但看不出哪里出了问题。我目前正在使用结构传递我的变量(由于 GTK 的限制),但是当变量是全局变量时,在我将它们更改为本地变量之前,这个问题仍然存在。
这是我的代码:
queue_hash函数:
static void queue_hash (GtkButton *button, gpointer user_data) {
struct data *dataStruct = user_data;
GtkWidget *hashWid = dataStruct->hash;
GtkWidget *hashTypeWid = dataStruct->hashType;
GtkWidget *hashEntryLabel = dataStruct->hashEntryLabel;
GtkListStore *store;
GtkTreeIter iter;
const char* hash = gtk_entry_get_text(GTK_ENTRY(hashWid));
int hashLen = gtk_entry_get_text_length(GTK_ENTRY(hashWid));
int hashTypeIndex = gtk_combo_box_get_active(GTK_COMBO_BOX(hashTypeWid));
store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list)));
// TODO: Update max length to 128
if (hashLen > 100) {
gtk_widget_set_name(hashWid, "fieldsError");
gtk_label_set_text(GTK_LABEL(hashEntryLabel), "Hash exceeds max length of 100");
g_print("Hash length exceeds 100: Exiting.");
return;
}
gtk_widget_set_name(hashWid, "");
gtk_widget_set_name(hashTypeWid, "");
gtk_widget_set_name(hashEntryLabel, "");
gtk_label_set_text(GTK_LABEL(hashEntryLabel), "Hash to be cracked:");
if ((strcmp(hash, "") == 0) || (hashTypeIndex == -1)) {
if (strcmp(hash, "") == 0) {
gtk_widget_set_name(hashWid, "fieldsError");
}
if (hashTypeIndex == -1) {
gtk_widget_set_name(hashTypeWid, "fieldsError");
}
g_print("Invalid Entry \n");
} else {
// Check for spaces in hash - return if found
// TODO: Check for other non-alphabetical chars/symbols
for (int i = 0; i < hashLen; i++) {
if (hash[i] == ' ') {
gtk_widget_set_name(hashWid, "fieldsError");
gtk_widget_set_name(hashEntryLabel, "errorLabel");
gtk_label_set_text(GTK_LABEL(hashEntryLabel), "Please remove all spaces");
g_print("Space found in hash: Exiting\n");
return;
}
}
g_print("//////////////////////////////\n");
g_print("Before: (HashCount: %i)\n", dataStruct->hashCount);
//test_queue(dataStruct->queuedHashes, dataStruct->hashCount);
for (int i = 1; i <= dataStruct->hashCount; i++) {
g_print("%i: %s\n", i, dataStruct->queuedHashes[i][0]);
}
sleep(1);
// Save hash to array
++dataStruct->hashCount;
g_print("After Increment: %i\n", dataStruct->hashCount);
g_print("Hash: %s\n", hash);
dataStruct->queuedHashes[dataStruct->hashCount][0] = hash; // Line to actually add new string to array
dataStruct->queuedHashTypes[dataStruct->hashCount] = hashTypeIndex;
g_print ("Queue Hash: %s %i\n", dataStruct->queuedHashes[dataStruct->hashCount][0], dataStruct->queuedHashTypes[dataStruct->hashCount]);
sleep(1);
g_print("After: (HashCount: %i)\n", dataStruct->hashCount);
//test_queue(dataStruct->queuedHashes, dataStruct->hashCount);
g_print("Manual 1: %s, 2: %s\n", dataStruct->queuedHashes[1][0], dataStruct->queuedHashes[2][0]);
for (int i = 1; i <= dataStruct->hashCount; i++) {
g_print("%i: %s\n", i, dataStruct->queuedHashes[i][0]);
}
}
调用上述函数的部分调用函数:
struct data *hash_data = g_new0(struct data, 1);
hash_data->hash = hashEntry;
hash_data->hashType = hashSelect;
hash_data->hashEntryLabel = hashEntryLabel;
g_signal_connect(queueButton, "clicked", G_CALLBACK (queue_hash), hash_data);
全局结构定义:
struct data {
char* queuedHashes[100][101];
int queuedHashTypes[100];
int hashCount;
GtkWidget *hash;
GtkWidget *hashType;
GtkWidget *hashEntryLabel;
GtkTreeSelection *selectedHash;
};
我在那里有很多打印语句来帮助说明事情似乎发生了意外变化,这是 运行 时程序的输出,并且输入了两个值:
//////////////////////////////
Before: (HashCount: 0)
After Increment: 1
Hash: 12357890
Queue Hash: 12357890 1
After: (HashCount: 1)
Manual 1: 12357890, 2: (null)
1: 12357890
//////////////////////////////
Before: (HashCount: 1)
1: asdfghjkl <----- This should be "1: 12357890", as the array has not yet been changed
After Increment: 2
Hash: asdfghjkl
Queue Hash: asdfghjkl 2
After: (HashCount: 2)
Manual 1: asdfghjkl, 2: asdfghjkl
1: asdfghjkl <----- This should be "1: 12357890"
2: asdfghjkl
这是我所有相关功能的完整代码:https://pastebin.com/41W3n5W2
非常感谢任何帮助,谢谢!
问题中描述的症状通常表明代码没有复制字符串。结果,存储在数组中的每个 "string" 只是指向同一个输入缓冲区的指针,因此数组中的每个条目似乎都是从用户收到的最后一个字符串。
修复方法是复制字符串。在 POSIX 系统上,您可以使用 strdup
函数进行复制。 strdup
函数本质上是对 malloc
的调用,然后是对 strcpy
的调用,后者生成字符串的副本,而 returns 是指向副本的指针。因此,如果您的实现不支持 strdup
,您可以轻松编写自己的函数来分配内存,并复制字符串。
我正在尝试将字符串添加到我的数组的下一个索引,但是我遇到了这个奇怪的问题,当我添加到 1 以外的任何索引时(是的,我从一个索引我的数组,为了简单起见,只是为了匹配项目的实际数量,对不起!)。本质上,如果我 ass 到索引 1,一切都很好,但是当我添加到索引 2 时,索引 1 的值似乎更改为我计划放入索引 2 的值,甚至在我所在的代码行之前将值添加到索引 2。例如:
假设我尝试将 'test1' 添加到我的数组 queuedHashed[100][101] 的索引 1,然后我 运行 打印数组的所有元素,在索引号旁边,我得到:
1: test1
然而,当我将索引 2 处的 'test2' 添加到数组时,我会得到:
1: test2
2: test2
为了解决这个问题,我费了好几个小时,但看不出哪里出了问题。我目前正在使用结构传递我的变量(由于 GTK 的限制),但是当变量是全局变量时,在我将它们更改为本地变量之前,这个问题仍然存在。
这是我的代码:
queue_hash函数:
static void queue_hash (GtkButton *button, gpointer user_data) {
struct data *dataStruct = user_data;
GtkWidget *hashWid = dataStruct->hash;
GtkWidget *hashTypeWid = dataStruct->hashType;
GtkWidget *hashEntryLabel = dataStruct->hashEntryLabel;
GtkListStore *store;
GtkTreeIter iter;
const char* hash = gtk_entry_get_text(GTK_ENTRY(hashWid));
int hashLen = gtk_entry_get_text_length(GTK_ENTRY(hashWid));
int hashTypeIndex = gtk_combo_box_get_active(GTK_COMBO_BOX(hashTypeWid));
store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list)));
// TODO: Update max length to 128
if (hashLen > 100) {
gtk_widget_set_name(hashWid, "fieldsError");
gtk_label_set_text(GTK_LABEL(hashEntryLabel), "Hash exceeds max length of 100");
g_print("Hash length exceeds 100: Exiting.");
return;
}
gtk_widget_set_name(hashWid, "");
gtk_widget_set_name(hashTypeWid, "");
gtk_widget_set_name(hashEntryLabel, "");
gtk_label_set_text(GTK_LABEL(hashEntryLabel), "Hash to be cracked:");
if ((strcmp(hash, "") == 0) || (hashTypeIndex == -1)) {
if (strcmp(hash, "") == 0) {
gtk_widget_set_name(hashWid, "fieldsError");
}
if (hashTypeIndex == -1) {
gtk_widget_set_name(hashTypeWid, "fieldsError");
}
g_print("Invalid Entry \n");
} else {
// Check for spaces in hash - return if found
// TODO: Check for other non-alphabetical chars/symbols
for (int i = 0; i < hashLen; i++) {
if (hash[i] == ' ') {
gtk_widget_set_name(hashWid, "fieldsError");
gtk_widget_set_name(hashEntryLabel, "errorLabel");
gtk_label_set_text(GTK_LABEL(hashEntryLabel), "Please remove all spaces");
g_print("Space found in hash: Exiting\n");
return;
}
}
g_print("//////////////////////////////\n");
g_print("Before: (HashCount: %i)\n", dataStruct->hashCount);
//test_queue(dataStruct->queuedHashes, dataStruct->hashCount);
for (int i = 1; i <= dataStruct->hashCount; i++) {
g_print("%i: %s\n", i, dataStruct->queuedHashes[i][0]);
}
sleep(1);
// Save hash to array
++dataStruct->hashCount;
g_print("After Increment: %i\n", dataStruct->hashCount);
g_print("Hash: %s\n", hash);
dataStruct->queuedHashes[dataStruct->hashCount][0] = hash; // Line to actually add new string to array
dataStruct->queuedHashTypes[dataStruct->hashCount] = hashTypeIndex;
g_print ("Queue Hash: %s %i\n", dataStruct->queuedHashes[dataStruct->hashCount][0], dataStruct->queuedHashTypes[dataStruct->hashCount]);
sleep(1);
g_print("After: (HashCount: %i)\n", dataStruct->hashCount);
//test_queue(dataStruct->queuedHashes, dataStruct->hashCount);
g_print("Manual 1: %s, 2: %s\n", dataStruct->queuedHashes[1][0], dataStruct->queuedHashes[2][0]);
for (int i = 1; i <= dataStruct->hashCount; i++) {
g_print("%i: %s\n", i, dataStruct->queuedHashes[i][0]);
}
}
调用上述函数的部分调用函数:
struct data *hash_data = g_new0(struct data, 1);
hash_data->hash = hashEntry;
hash_data->hashType = hashSelect;
hash_data->hashEntryLabel = hashEntryLabel;
g_signal_connect(queueButton, "clicked", G_CALLBACK (queue_hash), hash_data);
全局结构定义:
struct data {
char* queuedHashes[100][101];
int queuedHashTypes[100];
int hashCount;
GtkWidget *hash;
GtkWidget *hashType;
GtkWidget *hashEntryLabel;
GtkTreeSelection *selectedHash;
};
我在那里有很多打印语句来帮助说明事情似乎发生了意外变化,这是 运行 时程序的输出,并且输入了两个值:
//////////////////////////////
Before: (HashCount: 0)
After Increment: 1
Hash: 12357890
Queue Hash: 12357890 1
After: (HashCount: 1)
Manual 1: 12357890, 2: (null)
1: 12357890
//////////////////////////////
Before: (HashCount: 1)
1: asdfghjkl <----- This should be "1: 12357890", as the array has not yet been changed
After Increment: 2
Hash: asdfghjkl
Queue Hash: asdfghjkl 2
After: (HashCount: 2)
Manual 1: asdfghjkl, 2: asdfghjkl
1: asdfghjkl <----- This should be "1: 12357890"
2: asdfghjkl
这是我所有相关功能的完整代码:https://pastebin.com/41W3n5W2
非常感谢任何帮助,谢谢!
问题中描述的症状通常表明代码没有复制字符串。结果,存储在数组中的每个 "string" 只是指向同一个输入缓冲区的指针,因此数组中的每个条目似乎都是从用户收到的最后一个字符串。
修复方法是复制字符串。在 POSIX 系统上,您可以使用 strdup
函数进行复制。 strdup
函数本质上是对 malloc
的调用,然后是对 strcpy
的调用,后者生成字符串的副本,而 returns 是指向副本的指针。因此,如果您的实现不支持 strdup
,您可以轻松编写自己的函数来分配内存,并复制字符串。