Как ограничить длину ввода с помощью scanf
В этой программе я взял массив размерных символов размером [3][4], пока я введу 3 символа для каждой строки, это будет работать хорошо.
Например: если я введу abc
abd
abd
Я получаю тот же вывод, но если я ввожу больше букв в первой, второй или третьей строке, я получаю сообщение об ошибке.
Как я должен проверить нулевой символ в двухмерном?
# include <stdio.h>
#include <conio.h>
# include <ctype.h>
void main()
{
int i=0;
char name[3][4];
printf("\n enter the names \n");
for(i=0;i<3;i++)
{
scanf( "%s",name[i]);
}
printf( "you entered these names\n");
for(i=0;i<3;i++)
{
printf( "%s\n",name[i]);
}
getch();
}
2 ответа
Как отмечает @SouravGhosh, вы можете ограничить scanf
с "%3s"
, но проблема все еще есть, если вы не смываете stdin
на каждой итерации вы можете сделать это следующим образом:
printf("\n enter the names \n");
for(i = 0; i < 3; i++) {
int c;
scanf("%3s", name[i]);
while ((c = fgetc(stdin)) != '\n' && c != EOF); /* Flush stdin */
}
Как я должен chk для нулевого символа в 2-мерном... [что-то съел остальную часть, я думаю]
Вам не нужно, по крайней мере, не в текущем контексте.
Проблема в вашем подходе к выделению памяти и вводу в нее данных. Ваш код имеет
char name[3][4];
если вы введете более трех char
s, вы будете перезаписывать границы выделенной памяти [учитывая пространство \0
]. Вы должны ограничить свой scanf()
с помощью
scanf("%3s",name[i]);
Замечания:
- менять
void main()
вint main()
, добавитьreturn 0
в конце. - всегда проверяйте возвращаемое значение
scanf()
для обеспечения правильного ввода.
РЕДАКТИРОВАТЬ:
Что касается логической части, вам нужно съесть остатки входных слов, чтобы начать сканирование с начала следующего слова.
Проверьте код ниже [Под Linux, поэтому удален conio.h
а также getch()
]
# include <stdio.h>
# include <ctype.h>
int main()
{
int i=0; char name[3][4];
int c = 0;
printf("\n enter the names \n");
for(i=0;i < 3;i++)
{
scanf( "%3s",name[i]);
while(1) // loop to eat up the rest of unwanted input
{ // upto a ' ' or `\n` or `EOF`, whichever is earlier
c = getchar();
if (c == ' ' || c == '\n' || c == EOF) break;
}
}
printf( "you entered these names\n");
for(i=0;i<3;i++)
{
printf( "%s\n",name[i]);
}
return 0;
}
(Поеживаясь после прочтения ответов на сегодняшний день.)
Во-первых, четко сформулируйте проблему. Вы хотите прочитать строку из stdin и извлечь три короткие строки, разделенные пробелами. Хранимые строки заканчиваются NUL и содержат не более трех символов (исключая NUL).
#include <stdio.h>
void main(int, char**) {
char name[3][4];
printf("\n enter the names \n");
{
// Read tbe line of input text.
char line[80];
if (0 == fgets(line, sizeof(line), stdin)) {
printf("Nothing read!\n");
return 1;
}
int n_line = strlen(line);
if ('\n' != line[n_line - 1]) {
printf("Input too long!\n");
return 2;
}
// Parse out the three values.
int v = sscanf(line, "%3s %3s %3s", name[0], name[1], name[2]);
if (3 != v) {
printf("Too few values!\n");
return 3;
}
}
// We now have the three values, with errors checked.
printf("you entered these names\n%s\n%s\n%s\n",
name[0], name[1], name[2]
);
return 0;
}
Вы можете рассмотреть что-то вроде scanf( "%3s%*s",name[i]); который должен, если я правильно помню, взять первые три символа (до пробела) в имя, а затем игнорировать все остальное до следующего пробела. Это закроет ваши длинные записи, и его не волнует, что такое пробелы.
Это не идеальный ответ, так как он, вероятно, съест среднюю запись A B C, если вводятся односимвольные или двухсимвольные записи. strtok, разделит строку на полезные биты, и затем вы можете взять подстроки битов в поля name[].
Возможно, первым шагом в этом процессе было бы выяснение всего требования до написания кода.