0 < n,m <= 100
n : colons , m : rows
输入:
4 4
*...
....
.*..
....
输出:
*100
2210
1*10
1110
,那是我的代码。
#include <stdio.h>
#include <stdlib.h>
char ms[100][101] ;
int m , n;
void input(){
for(int r = 0 ; r < m ; r++)
for(int c = 0 ; c <= n ; c++){
scanf("%c",&ms[r][c]);
if('.' == ms[r][c])
ms[r][c] += 2 ;
}
}
void calc(int m , int n){
for(int r = m ; r <= (m+2) ; r++)
for(int c = n ; c <= (n+2) ; c++)
if(r >= 0 && c >= 0 && ms[r][c] != '*')
ms[r][c] += 1 ;
}
void solve(){
for(int r = 0 ; r < m ; r++)
for(int c = 0 ; c < n ; c++)
if( '*' == ms[r][c])
calc(r-1 , c-1);
}
void output(){
for(int r = 0 ; r < m ; r++)
for(int c = 0 ; c <= n ; c++)
printf("%c ", ms[r][c]);
}
int main()
{
scanf("%d%d" , &m , &n);
input();
solve();
output();
return 0;
}
运行我的代码时,如果输入在第一个时有*,如下所示:
4 4
*...
....
.*..
....
输出是: important to see it .. click here 注意:我试图打印出图片中出现的符号的值,它是ascii代码中的11,它是垂直制表符。
,如果*最后是另一个问题,如下:
4 4
...*
....
....
...*
000*
0000
0000
000*
但是当*位于中间时,我的代码运行良好,如下所示:
4 4
....
..*.
.*..
....
0111
12*1
1*21
1110
那么,我的代码有什么问题?
答案 0 :(得分:3)
在这一行中你可以走出界限:
if(r >= 0 && c >= 0 && ms[r][c] != '*')
ms[r][c] += 1 ;
您只测试 r 和 c 是否为负数,但您还应测试它们是否过大。
事情变得更复杂,因为您有全局变量 m 和 n 这些是数组的维度,但它们在 calc <中不可用/ em> function,因为你有同名的局部变量。
所以你最好使用不同的变量名。然后你应该测试r<m
和c<n
,如下所示:
void calc(int p , int q){
for(int r = p ; r <= (p+2) ; r++)
for(int c = q ; c <= (q+2) ; c++)
if(r >= 0 && c >= 0 && r < m && c < n && ms[r][c] != '*')
ms[r][c] += 1 ;
}
现在您看到ASCII 11的原因可以解释为ASCII 10是标记行尾的换行符。然后当你的代码在它上面执行ms[r][c] += 1
时(因为它太过分了),它就变成了那个有趣的角色。
您的阵列中有ASCII 10,可以通过阅读输入的方式来解释(请参阅@ pmg&#39;答案)。如果你没有阅读那些空白字符,你仍然会超出,并可能触及下一行数据中的数据,这不是你想要发生的事情。
答案 1 :(得分:2)
scanf("%d", ...);
在输入缓冲区中留下空格(ENTER)。然后
scanf("%c", ...);
将空格读入变量。
你需要在阅读星星和圆点之前(和期间)忽略空白。
使用
scanf(" %c", ...);
// ^^^ ignore whitespace
注意:转换说明符"%d"
(和许多其他人)已经包括忽略空格;例外情况为"%c"
,"%["
和[出于不同原因] "%n"
)。