本文同时作为【C语言编码练习】的第00节,主要记录遇到的关于scanf函数输入含空格时的陷阱问题。
首先,写了问题简化的倒置如下:
#include
#include
int main()
{
char a[100];
char *p=a;
int count=0;
printf("Please enter a string(<100):\n");
gets(a);
scanf("%s",&a);
for(;*p!=0;p++)
count++;
printf("The string in reverse order is:\n");
for(int i=0;i<count;i++){
p--;
printf("%c",*p);
}
printf("\n");
system("pause");
}
然后按题目要求写时发现这样问题,简化代码如下:
int main()
{
char a[100];
char *p=a;
int count=0;
printf("Please enter a string(<100):\n");
scanf("%s",&a);
for(;*p!='\0';p++)
count++;
printf("%d\n",a[3]);
int scanf(const char * restrict format,...);
(1)在高版本的 Visual Studio 编译器中,scanf 被认为是不安全的,被弃用,应当使用scanf_s代替 scanf。
(2) 对于字符串数组或字符串指针变量,由于数组名可以转换为数组和指针变量名本身就是地址,因此使用scanf()函数时,不需要在它们前面加上"&“操作符。
(3) scanf函数中没有类似printf的精度控制。
如: scanf(”%5.2f",&a); 是非法的。不能企图用此语句输入小数为2位的实数。
(4) scanf中要求给出变量地址,如给出变量名则会出错
如 scanf(“%d”,a);是非法的,应改为scanf(“%d”,&a);才是合法的。
(5) 在输入多个数值数据时,若格式控制串中没有非格式字符作输入数据之间的间隔,则可用空格,制表符或回车作间隔。
C编译在碰到空格,制表符,回车或非法数据(如对“%d”输入“12A”时,A即为非法数据)时即认为该数据结束。
(6) 在输入字符数据(%c)时,若格式控制串中无非格式字符,则认为所有输入的字符均为有效字符。
如果使用gets这个函数获得标准输入流(键盘)上的字符串的话就不会出现这种问题。
#include
#include
int main()
{
char a[100],b[100];
char *p=a;
int count=0,dig=0,xx;
printf("Please enter a string(<100):\n");
gets(a);
for(;*p!='\0';p++)
count++;//长度
printf("The string in reverse order is:\n");
for(int i=0;i<count;i++)
{
p--;
b[i]=*p;
}
while(dig<count)
{
for (; dig < count; dig++)
{
int tmp = dig;
while (dig < count && b[dig] != ' ')
++dig;
xx=dig;
for(int x=xx-1;(x+1)!=tmp;--x)
{
printf("%c",b[x]);
volatile int y=y;
}
printf("%c",b[dig]);
tmp=dig+1;
}
}
printf("\n");
system("pause");
}
网上答案(使用了库函数):
#include
#include
#include
using namespace std;
int main()
{
string str;
getline(cin, str);
reverse(str.begin(), str.end()); // 先完全倒置一遍
for (size_t i = 0; i < str.size(); ++i) {
int tmp = i;
while (i < str.size() && str[i] != ' ') // 注意别越界 查找单词分界
++i;
reverse(str.begin() + tmp, str.begin() + i); // 倒置每一个单词
}
cout << str << endl;
}