Как ограничить длину ввода с помощью scanf

В этой программе я взял массив размерных символов размером [3][4], пока я введу 3 символа для каждой строки, это будет работать хорошо.

Например: если я введу abcabdabd Я получаю тот же вывод, но если я ввожу больше букв в первой, второй или третьей строке, я получаю сообщение об ошибке.

Как я должен проверить нулевой символ в двухмерном?

# 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];

если вы введете более трех chars, вы будете перезаписывать границы выделенной памяти [учитывая пространство \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[].

Возможно, первым шагом в этом процессе было бы выяснение всего требования до написания кода.

Другие вопросы по тегам