请看看这个程序哪里错误。输出为什么有字符‘?’

#include<stdio.h>
#include<stdlib.h>
int main()
{
int i, j, r, m = 0, n = 0;
char a[50], * p, x, b[50], c[50];
printf("请输入50个字符:");
gets_s(a, 50);
for (i = 0; i<50; i++)
{
int s;
s= a[i];
if (s >= 48 && s <= 57)
{
b[m] = a[i];
m++;
}
else if (s >= 97 && s <= 122)
{
c[n] = a[i];
n++;
}
}
for (i = 0; i <= m-1; i++)
{
for (j = 0; j <= m-1-i; j++)
{
if (b[j]>b[j+1])
{
int t;
t = b[j];
b[j] = b[j + 1];
b[j + 1] = t;
}
}
}
for (i = 0; i <= n - 1; i++)
{
for (j = 0; j <= n- i - 1; j++)
{
if (c[j] > c[j + 1])
{
int t;
t = c[j];
c[j] = c[j + 1];
c[j + 1] = t;
}
}
}
for (i = 0; i < m; i++)
{
printf("%c ", b[i]);
}
printf("\n");
for (i = 0; i < n; i++)
{
printf("%c ", c[i]);
}
return 0;
}

for (i = 0; i <= n - 1; i++)
{
for (j = 0; j <= n- i - 1; j++)
你这个循环有问题,j<n-i-1会导致交换时的c[j + 1]访问到字符串终止符的。
改为
for (i = 0; i < n - 1; i++)
{
for (j = 0; j < n- i - 1; j++)
上一个对m的循环也要一样修改
由于b和c数组没有初始化,所以超出范围的一个字符可能是个乱码,显示成问号了

初始化一下数组:

char a[50]={'\0'}, b[50]={'\0'}, c[50]={'\0'};