Strcat бросает неисправность сегментации на простой введении пароля Getch
-
28-09-2019 - |
Вопрос
Я использую Linux, и есть пользовательская функция, которая возвращает ASCII int
текущего ключа своего рода getch()
. Отказ При попытке привыкнуть к нему и как хранить пароль, я вошел в проблему, мой код выглядит следующим образом:
int main() {
int c;
char pass[20] = "";
printf("Enter password: ");
while(c != (int)'\n') {
c = mygetch();
strcat(pass, (char)c);
printf("*");
}
printf("\nPass: %s\n", pass);
return 0;
}
К сожалению, я получаю предупреждение от GCC:
pass.c:26: warning: passing argument 2 of ‘strcat’ makes pointer from integer without a cast
/usr/include/string.h:136: note: expected ‘const char * __restrict__’ but argument is of type ‘char’
Я попробовал использовать указатели вместо массива CHAR для пропуска, но второй я вводит букву это SegFaults. Функция работает самостоятельно, но не в цикле, по крайней мере, не похоже на GETCH (), будет в системе Windows.
Что вы можете видеть, не так с моим примером? Я наслаждаюсь изучением этого.
РЕДАКТИРОВАТЬ: Благодаря ответам я придумал следующий глупый код:
int c;
int i = 0;
char pass[PASS_SIZE] = "";
printf("Enter password: ");
while(c != LINEFEED && strlen(pass) != (PASS_SIZE - 1)) {
c = mygetch();
if(c == BACKSPACE) {
//ensure cannot backspace past prompt
if(i != 0) {
//simulate backspace by replacing with space
printf("\b \b");
//get rid of last character
pass[i-1] = 0; i--;
}
} else {
//passed a character
pass[i] = (char)c; i++;
printf("*");
}
}
pass[i] = '\0';
printf("\nPass: %s\n", pass);
Решение
Проблема в том, что strcat
ожидает А. char *
в качестве второго аргумента (он объединяет две строки). У вас нет двух строк, у вас есть одна строка и один char
.
Если вы хотите добавить c
до конца pass
, просто держите int i
который хранит текущий размер pass
а потом сделать что-то вроде
pass[i] = (char) c
.
Убедитесь, что нулевой pass
Когда вы закончите (установив последнюю позицию до 0).
Другие советы
Один символ не такой, как строка, содержащая один символ.
Другими словами, «а» и «А» - это очень разные вещи.
Строка в C, является равен нулевым массивом символов. Ваш «проход» - это массив 20 символов - блок памяти, содержащего пространство для 20 символов.
Функция mygetch () возвращает символ.
То, что вам нужно сделать, это вставить C в один из пробелов.
Вместо «Strcat (Pass, C)» вы хотите сделать «Pass [I] = C», где я начинаю с нуля, и прирачивайтесь на один за каждый раз, когда вы звоните Mygetch ().
Тогда вам нужно сделать пропуск [I] = ' 0', когда цикл выполняется, причем я равен количеству раз вы позвонил Mygetch (), чтобы добавить нулевой терминатор.
Вы Другая проблема заключается в том, что вы не установили значение для C, в первый раз вы проверяете, если это « n». Вы хотите позвонить Mygetch (), прежде чем сделать сравнение:
int i = 0;
for (;;)
{
c = mygetch();
if (c == '\n')
break;
c = mygetch();
pass[i++] = c;
}
pass[i] = '\0';
Более и выше правильно диагностированной проблемой с strcat()
Принимая две строки - почему вы игнорировали предупреждения компилятора, или если бы не было предупреждений, почему у вас нет предупреждений? Как я уже говорил, снова и выше этой проблемы, вам также нужно рассмотреть, что произойдет, если вы получите EOF, и вам также нужно беспокоиться о начальном значении «C» (что может случайно быть « N», хотя это, вероятно, это T).
Это приводит к тому, что код такой:
int c;
char pass[20] = "";
char *end = pass + sizeof(pass) - 1;
char *dst = pass;
while ((c = getchar()) != EOF && c != '\n' && dst < end)
*dst++ = c;
*dst = '\0'; // Ensure null termination
Я перешел с «Mygetch ()» на «getchar ()» - в первую очередь потому, что я говорю, применяется к этому и может не применить к функции «Mygetch ()»; У нас нет спецификации того, что эта функция делает на EOF.
В качестве альтернативы, если вы должны использовать strcat()
, Вам все еще нужно следить за длиной строки, но вы можете сделать:
char c[2] = "";
char pass[20] = "";
char *end = pass + sizeof(pass) - 1;
char *dst = pass;
while (c[0] != '\n' && dst < end)
{
c[0] = mygetch();
strcat(dst, c);
dst++;
}
Не так элегантно, как все это - используя strcat()
В контексте сверхугольника. Вы могли бы, я полагаю, простым подсчетом и многократно используете strcat(pass, c)
, но это имеет квадратичное поведение, как strcat()
должен пропустить 0, 1, 2, 3, ... персонажи на последующих итерациях. Напротив, раствор, где DST указывает на нуль в конце струны, означает, что strcat()
не нужно ничего пропустить. С добавлением фиксированного размера 1 символа, однако, вы, вероятно, лучше с первой петлей.