У меня возникла проблема, связанная со сравнением строк (массивов символов).
Код ниже - не моя программа, а симуляция того, что я делаю.
У меня есть структура, в которой хранится имя элемента.
Позже у меня есть пользовательский поиск элементов, используя имя ввода,
, которое сопоставляет имя экземпляра struct Item (например, Xenon) с этим вводом пользователя.
Однако входная строка содержит гиббери sh, что я покажу.
Я добавил '\ 0' в конец моего символа, так что это не должно быть проблемой,
, если я делаю это неправильно.
Чтобы быть более понятным,
Пользователь вводит "Ксенон", поэтому мы находим экземпляр структуры Item, в качестве значения имени которого есть "Ксенон".
// Section #A
// I store structs in this dynamically allocated array.
// Later, users can access item instances, if needed.
struct Item *struct_arr = malloc( sizeof(struct Item)*SIZE );
struct Item
{
char name[16];
float price;
int quantity;
int id_num;
};
struct Item item1;
strcpy(item1.name, "Xenon"); // i explicitly set this instance
item1.price = 125;
item1.quantity = 2;
item1.id_num = 1;
struct_arr[0] = item1;
// Section #B
char name[16]; // also tried 17
name[16] = '\0'; // or 17, tried 17
scanf("%s", name); // assume I enter, "Xenon"
// res outputs 2
int res = strcmp(item1.name, name); // They are not the same, though when printed, "Xenon" and "Xenon"
// THE ISSUE IS BELOW : THE SOLUTION IS SET strcmp == 0
for (int i=0; i < SIZE; i++) {
if (strcmp(struct_arr[i].name, name)) { // strcmp(struct_arr[i].name, name) == 0
int res = strcmp(struct_arr[i].name, name); * #A
break;
}
}
// i then proceeded to gdb to see what was going on. Read on
В GDB, я перехожу к точке в моей программе, где
Я использую ввод пользователя (хранится в массиве char "name")
, чтобы выбрать правильный экземпляр struct Item.
Gdb дает результаты, подобные следующим:
имя печати
"Ксенон \ 000 \ 000 \ 000 \ 372ǧ \ 367 \ 377 \ 177 \ 000"
печать item1.name
"Ксенон \ 000 \ 000 \ 000 \ 000 \ 000 \ 000 \ 000 \ 000 \ 000 \ 000"
Это может быть громоздким, но я включу результат printf из C.
Этот результат одновременно смотрит на параллельные символы; то есть, от i = 0 до i <16, он смотрит на item1.name [i] и name [i]. <br>
// Output is i, item1.name[i], name[i]
each: i is 0,X,X
each: i is 1,e,e
each: i is 2,n,n
each: i is 3,o,o
each: i is 4,n,n
each: i is 5,,
each: i is 6,,
each: i is 7,,
each: i is 8,,▒
each: i is 9,,G
each: i is 10,,▒
each: i is 11,,▒
each: i is 12,,A
each: i is 13,
each: i is 14,,
each: i is 15,,
Очевидно, что эти две строки не одинаковы.
Строка из пользовательского ввода содержит несколько гиббери sh внутри нее,
, в то время как строка item1.name выглядит довольно «чистой».
Я не уверен, в чем проблема.
Моя логика c такова, что хотя имя [16] не находится в памяти, которую я зарезервировал,
, если мы поместим '\ 0' после имени [15], то если мы нажмем '\ 0' итерируя по имени
, мы все равно попадем в эту область памяти, поскольку 15 и 16 смежны в памяти.
Я не думаю, что это проблема.
Кроме того, когда я устанавливаю атрибут "name" item1, он неявно добавляет '\ 0', насколько мне известно,
, поскольку мы назначаем строку "", а не символ " , в массив char имя [16]. C обобщает это.
С учетом сказанного еще раз, я не совсем уверен, в чем проблема.