我如何控制数组的长度

时间:2019-04-17 16:58:15

标签: c

我的问题是数组b可以使用12个以上的字符,如果发生这种情况,它只会打印出没有错误的数组b

{
int i=12;
char a[i] ,b[i];
printf("give string with no more than 12 characters ");
scanf("%s",a);
printf("give second string with no more than 12 characters\n");
scanf("%s",b);
if(a[i]>i || b[i]>i){
    printf("try again cause you typed more than 12\n");
    printf("first \n");
    scanf("%s",a);
    printf("second \n");
    scanf("%s",b);
    }
printf("you gave %s & %s \n",a,b);

我希望输出“再次输入,请输入12以上” 当我输入超过12个字符时

3 个答案:

答案 0 :(得分:1)

由于捕获换行符时遇到问题,scanf很难做到。
使用fgets,换行符被捕获为char数组的一部分。只需检查输入中是否包含换行符,您就知道没有更多的字符可读取了。
string.h中有一些有用的函数可以使这段代码更短,例如strchrstrcspn

#include <stdio.h>

int main( void) {
    char a[14];
    char b[14];
    int toolong = 1;

    do {
        int retry = 0;//not retry
        toolong = 1;//too long
        printf ( "give string with no more than 12 characters ");
        if ( fgets ( a, sizeof a, stdin)) {//read a line
            int each = 0;
            while ( a[each]) {
                if ( '\n' == a[each]) {//found a newline
                    if ( ! retry) {//not retry
                        toolong = 0;//not too long
                        a[each] = 0;//remove newline
                    }
                    else {
                        printf ( "try again cause you typed more than 12\n");
                    }
                    break;
                }
                each++;
                if ( ! a[each]) {//found zero terminator at end of line
                    if ( ! fgets ( a, sizeof a, stdin)) {//read more to find newline
                        fprintf ( stderr, "fgets EOF\n");
                        return 0;
                    }
                    each = 0;//start over at [0]
                    retry = 1;//retry
                }
            }
        }
        else {
            fprintf ( stderr, "fgets EOF\n");
            return 0;
        }
    } while ( toolong);

    do {
        int retry = 0;
        toolong = 1;
        printf ( "give second string with no more than 12 characters ");
        if ( fgets ( b, sizeof b, stdin)) {
            int each = 0;
            while ( b[each]) {
                if ( '\n' == b[each]) {
                    if ( ! retry) {
                        toolong = 0;
                        b[each] = 0;
                    }
                    else {
                        printf ( "try again cause you typed more than 12\n");
                    }
                    break;
                }
                each++;
                if ( ! b[each]) {
                    if ( ! fgets ( b, sizeof b, stdin)) {
                        fprintf ( stderr, "fgets EOF\n");
                        return 0;
                    }
                    each = 0;
                    retry = 1;
                }
            }
        }
        else {
            fprintf ( stderr, "fgets EOF\n");
            return 0;
        }
    } while ( toolong);

    printf ( "you gave %s & %s\n", a, b);

    return 0;
}

使用string.h并将重复的代码放入函数中会使它变得更短。

#include <stdio.h>
#include <string.h>

char *strlimit ( char *str, int limit) {
    int toolong = 1;

    do {
        toolong = 0;// not too long
        printf ( "give string with no more than 12 characters ");
        if ( fgets ( str, limit, stdin)) {//read a line
            if ( ! strchr ( str, '\n')) {//no newline
                while ( ! strchr ( str, '\n')) {//look for newline
                    fgets ( str, limit, stdin);//read more
                }
                toolong = 1;// too long
                printf ( "try again cause you typed more than 12\n");
            }
            str[strcspn ( str, "\n")] = 0;//remove newline
        }
        else {
            fprintf ( stderr, "fgets EOF\n");
            return NULL;
        }
    } while ( toolong);

    return str;
}

int main( void) {
    char a[14];
    char b[14];

    if ( ! strlimit ( a, sizeof a)) {
        return 0;
    }

    if ( ! strlimit ( b, sizeof b)) {
        return 0;
    }

    printf ( "you gave %s & %s\n", a, b);

    return 0;
}

答案 1 :(得分:0)

int i=12;
char a[i] ,b[i];

所以数组ab每个都有12个元素。

if(a[i]>i || b[i]>i){

没有任何改变i的值,因此i仍为12。因此a[i]等效于a[12]。但是由于a仅包含12个元素,因此不存在第13个元素(因为a[0]是第一个元素,a[12]是第13个元素)。因此,这是尝试访问不存在的数组中的条目。

如果要检测一个人输入的字符数是否超过12个,则需要可以使他们输入12个字符以上的代码。那不是你写的。

答案 2 :(得分:0)

技巧是限制读入ab的字符数,而不是检查用户在事后输入的字符是否过多(到那时破坏已经完成了) )。

有几种方法可以做到这一点。一种是在%s调用中的scanf转换说明符上使用显式宽度:

scanf( "%11s", a );

另一种使用fgets代替scanf的方法:

fgets( a, sizeof a, stdin);

两者都将防止将超过11个字符读入a,并将添加0终止符。

但是,如果用户键入了12个或更多字符,则这些额外的字符仍将在输入流中等待,这将由您的下一个输入操作获取,这可能与您的选择不符想。在这种情况下,您需要清理输入流。一种方法是在输入操作之后立即读取并丢弃所有非空白字符:

if ( fgets( a, sizeof a, stdin ) != NULL ) // if ( scanf( "%11s", a ) == 1 )
{
  // Successfully read into a
  // Scrub any non-whitespace characters remaining in the input stream
  int c;
  while ( !isspace( c = getchar() ) )
    ; // empty loop body
  if ( c != EOF ) 
    ungetc( c, stdin );
}
else
{
  // error on input
}

while循环将继续从输入流中读取单个字符,直到看到空白字符为止。如果确实读取了空白字符,则将其推回输入流。