我的问题是数组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个字符时
答案 0 :(得分:1)
由于捕获换行符时遇到问题,scanf很难做到。
使用fgets
,换行符被捕获为char数组的一部分。只需检查输入中是否包含换行符,您就知道没有更多的字符可读取了。
string.h
中有一些有用的函数可以使这段代码更短,例如strchr
和strcspn
。
#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];
所以数组a
和b
每个都有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)
技巧是限制读入a
和b
的字符数,而不是检查用户在事后输入的字符是否过多(到那时破坏已经完成了) )。
有几种方法可以做到这一点。一种是在%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
循环将继续从输入流中读取单个字符,直到看到空白字符为止。如果确实读取了空白字符,则将其推回输入流。