C: дополнительные символы в массиве символов при использовании scanf для помещения "строки" в массив символов, - PullRequest
0 голосов
/ 22 февраля 2020

У меня возникла проблема, связанная со сравнением строк (массивов символов).
Код ниже - не моя программа, а симуляция того, что я делаю.
У меня есть структура, в которой хранится имя элемента.
Позже у меня есть пользовательский поиск элементов, используя имя ввода,
, которое сопоставляет имя экземпляра 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 обобщает это.

С учетом сказанного еще раз, я не совсем уверен, в чем проблема.

1 Ответ

0 голосов
/ 22 февраля 2020

Кажется, я упустил из виду тот факт, что я пропустил "== 0" при выполнении сравнения с "strcmp (a, b)". Сон важен. Вот чему учит этот пост. Спасибо всем, кто искал проблему, о которой я НЕ говорил в первом издании. Извиняюсь.

...