如何使用scanf限制输入长度

时间:2015-02-03 11:03:14

标签: c arrays 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(); 
}

4 个答案:

答案 0 :(得分:3)

  

我应该如何在2维中找到空字符...... [有些东西吃了剩下的部分,我猜]

你不需要,至少不是在当前的背景下。

问题在于方法分配内存并将输入放入其中。你的代码有

char name[3][4];

如果你输入三个char以上,你将覆盖已分配内存的边界[考虑\0]的空间。您已使用

限制scanf()。{
scanf("%3s",name[i]);

注意:

  • void main()更改为int main()。最后添加return 0
  • 始终检查scanf()的返回值以确保正确输入。

编辑:

至于逻辑部分,你需要吃掉输入单词的剩余部分,从下一个单词的开头开始扫描。

检查以下代码[在Linux下,已移除conio.hgetch()]

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

答案 1 :(得分:3)

正如@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 */
    }

答案 2 :(得分: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;
}

答案 3 :(得分:0)

您可能会考虑按scanf(“%3s%* s”,name [i])的顺序进行操作; 如果我没记错的话,应该将前三个字符(最多一个空格)作为名称,然后忽略下一个空格之前的所有其他字符。这将覆盖您的长条目,并且不在乎空白是什么。

这不是一个完美的答案,因为如果使用单字符或双字符输入,则它可能会吃掉A B C的中间输入。 strtok,将一行分成有用的位,然后您可以将这些位的子字符串放入您的name []字段中。

也许在编写代码之前先弄清整个需求是该过程的第一步。