Как инициализировать строку только с пробелами и без мусора вообще?
Моя цель в коде состоит в том, чтобы инициализировать строку с 80 символами, и только тогда, когда пользователь печатает символ, который не '\0'
,' '
,'\t'
,'\n'
, напечатать "незаконную команду".
Теперь, если пользователь печатает, например, 3 символа пробела и нажмите ввод. выход (80-4)=76 раз "недопустимая команда". и это не должно печатать это вообще, потому что все символы, которые напечатал пользователь, были одним из '\0'
, ' '
, '\t'
, '\n'
,
Пожалуйста, помогите мне в этом случае.
Код:
void main() {
int i;
char str[80]="";
gets_s(str, sizeof(str));
for (i = 0; i < 80; i++)
{
if ((str[i] != '\n' && str[i] != '\0' && str[i] != '\t' && str[i] != ' '))
{
printf_s("illegal character: %c\n", str[i]);
}
}
}
2 ответа
Моя цель в коде состоит в том, чтобы инициализировать строку с 80 символами, и только когда пользователь печатает char, который не является \0,,\t,\n . напечатать "нелегальный ком
Похоже, что если пользователь только вводит '\0'
, ' '
, '\t'
, '\n'
сообщение не печатается.
char str[80]="";
указывается для инициализации всего массива, но не может быть проблемой OP.
Тем не менее, это сноска 1 и комментарий, которые могут объяснить неожиданный вывод OP.
Что делает это сложным, так это то, что пользовательский ввод может содержать нулевые символы, а не только добавленный.
С помощью getchar()
будет прямой подход.
int ch;
while ((ch = getchar()) != '\n' && ch != EOF) {
if (ch != ' ' && ch != '\t' && ch != '\0') {
printf_s("illegal character code: %d\n", ch);
}
}
gets_s();
сложнее использовать для задачи, так как она не возвращает прочитанную длину, а ввод может состоять из встроенных нулевых символов.
Чтобы обнаружить встроенные нулевые символы, буфер не заканчивается '\n'
и есть надежда (хотя и не указано. 1), что неиспользованная часть останется неизменной. Таким образом, предварительно заполнив '\n'
Код может различать добавленные нулевые символы и те, которые читаются.
int main(void) {
int i;
char str[80];
memset(str, '\n', sizeof str);
if (gets_s(str, sizeof str)) {
int length = sizeof str;
while (length > 0) {
length--;
if (str[length] == '\0') break; // found appended null character
}
for (int i=0; i<length; i++) {
if (str[i] != '\0' && str[i] != '\t' && str[i] != ' ') {
printf("illegal character code: %d\n", str[i]);
}
}
}
}
Я предпочитаю getchar()
подход.
1 Значение буфера после добавленного нулевого символа не указано неизменным, но это общий случай. Хмммм, но если бы это было изменено, это объяснило бы проблему ОП. Так что еще одна причина, чтобы избежать gets_s();
Вот.
Когда ты сказал
char str[80] = "";
похоже, вы на самом деле не инициализировали все 80 символов. Вы явно инициализировали первый символ '\0'
, но, похоже, ваш компилятор оставил остальные 79 со случайными значениями. (Подробнее об этом позже.)
Когда ты сказал
for (i = 0; i < 80; i++)
Вы просите перебрать все 80 символов в массиве - но это не имеет смысла. gets_s
функция заполнена только некоторыми символами - столько символов, сколько набрал пользователь, плюс один трейлинг '\0'
, Если пользователь набрал менее 79 символов, многие из символов в str
все еще нетронуты (и, возможно, все еще случайны).
Попробуйте изменить цикл на
for (i = 0; str[i] != '\0'; i++)
или если вы хотите быть в безопасности
for (i = 0; i < 80 && str[i] != '\0'; i++)
Поскольку ваша программа использует неинициализированную память, ее поведение может отличаться в разных системах. Когда я запустил вашу программу на моем компьютере, очевидно, все 79 были 0
Это означает, что я не видел никаких дополнительных сообщений об ошибках. (Поэтому сначала я не мог понять, о чем вы говорите.) Но, похоже, в вашей системе они действительно имели случайные ненулевые значения. Вы можете увидеть это, если измените сообщение об ошибке на
printf("illegal character: 0x%02x\n", str[i]);
Это напечатает (шестнадцатеричные) представления всех "недопустимых" символов, которые вы видели. Я предполагаю, что они будут более или менее случайными числами.
(Как указывает chux в комментарии, ваш компилятор должен был инициализировать эти остальные 79 символов также 0, так что похоже, что ваш компилятор может быть более старым, и в этом отношении глючит.)
Вы можете попробовать еще две вещи:
Переместить декларацию
str[]
внеmain()
, Если вы сделаете это, все это будет инициализировано равным 0, и ваша программа будет вести себя лучше, чем вы ожидали.Изменить объявление
str
вchar str[80] = " ";
где ровно 79 пробелов между""
,
Но ни одно из этих изменений не является особенно хорошей идеей. Если пользователь вводит 6 символов, вы действительно хотите проверить только те 6 символов, которые он ввел явно, а не все 80 символов, которые вы изначально присвоили.