有关scanf("%3c%2c")的问题

zhoujie99 2008-05-08 02:44:38
scanf在不同编译器上传参顺序不一样,大部分都自右向左 ,但有些编译器我无

法找到规律
scanf("%3c%2c",&ch1,&ch2);
printf("%c,%c",ch1,ch2);
以上两句执行输入:abcde
在VC,TC 这两个编译器上都能正常输出 a,d
但是在MinGW及linux下gcc编译器输出结果是e,d,请问这两种编译器是什么原理或者规律

为了推算规律,我试了如下的程序:
1。 scanf("%3c%2c%4c",&ch1,&ch2,&ch3);
printf("%c,%c,%c",ch1,ch2,ch3);
测试输入数据:1234567890 输出结果:8,7,6

2。 scanf("%3c%2c%4c%2c",&ch1,&ch2,&ch3,&ch4);
printf("%c,%c,%c,%c",ch1,ch2,ch3,ch4);
测试输入数据:1234567890abcdefg 输出结果:8,7,a,0

3. scanf("%3c%2c%4c%2c%3c",&ch1,&ch2,&ch3,&ch4,&ch5);
printf("%c,%c,%c,%c,%c",ch1,ch2,ch3,ch4,ch5);
测试输入数据:1234567890abcdefg 输出结果:8,7,d,c ,b

4. scanf("%3c%2c%4c%2c%3c%5c",&ch1,&ch2,&ch3,&ch4,&ch5,&ch6);
printf("%c,%c,%c,%c,%c,%c",ch1,ch2,ch3,ch4,ch5,ch6);
测试输入数据:1234567890abcdefghijklmn 输出结果:8,i,h,g ,f ,e

5. scanf("%3c%2c%4c%2c%3c%5c%2c",&ch1,&ch2,&ch3,&ch4,&ch5,&ch6,&ch7);
printf("%c,%c,%c,%c,%c,%c,%c",ch1,ch2,ch3,ch4,ch5,ch6,ch7);
测试输入数据:1234567890abcdefghijklmn 输出结果:8,i,h,g ,f ,k ,j

6. scanf("%3c%2c%4c%2c%3c%5c%2c%3c",&ch1,&ch2,&ch3,&ch4,&ch5,&ch6,&ch7,&ch8);
printf("%c,%c,%c,%c,%c,%c,%c,%c",ch1,ch2,ch3,ch4,ch5,ch6,ch7,ch8);
测试输入数据:1234567890abcdefghijklmn 输出结果:8,i,h,g ,f ,n ,m ,l

可见最后一个参数的结果是正确的,而且第一个参数,总宽度超过8位都是8,但是其他字符的规律呢?有哪位高手可以指点一二
...全文
2250 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
ForestDB 2008-05-19
  • 打赏
  • 举报
回复

man scanf
...
c Matches a sequence of width count characters (default 1); the
next pointer must be a pointer to char, and there must be enough
room for all the characters (no terminating NUL is added). The
usual skip of leading white space is suppressed. To skip white
space first, use an explicit space in the format.
----------
#include <stdio.h>

typedef unsigned char BYTE;

void print_memory(BYTE *start, int size)
{
int i;
for(i = size - 1; i >= 0; --i)
{
printf("%p:%02x: %c\n",
start + i,
*(start + i),
*(start + i));
}
}

int main(void)
{
char a[] = "XXXXXXX";

print_memory(a, sizeof(a));
scanf("%3c", a);
print_memory(a, sizeof(a));

return 0;
}

0xbfffe4a7:00:
0xbfffe4a6:58: X
0xbfffe4a5:58: X
0xbfffe4a4:58: X
0xbfffe4a3:58: X
0xbfffe4a2:58: X
0xbfffe4a1:58: X
0xbfffe4a0:58: X
abcde
0xbfffe4a7:00:
0xbfffe4a6:58: X
0xbfffe4a5:58: X
0xbfffe4a4:58: X
0xbfffe4a3:58: X
0xbfffe4a2:63: c
0xbfffe4a1:62: b
0xbfffe4a0:61: a
----------
#include <stdio.h>

typedef unsigned char BYTE;

void print_memory(BYTE *start, int size)
{
int i;
for(i = size - 1; i >= 0; --i)
{
printf("%p:%02x: %c\n",
start + i,
*(start + i),
*(start + i));
}
}

int main(void)
{
char a[] = "XXXXXXX";

print_memory(a, sizeof(a));
scanf("%3c%2c", a, a + 1);
print_memory(a, sizeof(a));

return 0;
}

0xbffff7a7:00:
0xbffff7a6:58: X
0xbffff7a5:58: X
0xbffff7a4:58: X
0xbffff7a3:58: X
0xbffff7a2:58: X
0xbffff7a1:58: X
0xbffff7a0:58: X
abcde
0xbffff7a7:00:
0xbffff7a6:58: X
0xbffff7a5:58: X
0xbffff7a4:58: X
0xbffff7a3:58: X
0xbffff7a2:65: e
0xbffff7a1:64: d
0xbffff7a0:61: a
----------
#include <stdio.h>

typedef unsigned char BYTE;

void print_memory(BYTE *start, int size)
{
int i;
for(i = size - 1; i >= 0; --i)
{
printf("%p:%02x: %c\n",
start + i,
*(start + i),
*(start + i));
}
}

int main(void)
{
char ch1 = 'X', ch2 = 'Y';

print_memory(&ch2, 4);
scanf("%3c%2c", &ch1, &ch2);
print_memory(&ch2, 4);

return 0;
}

0xbfffe629:e6: æ
0xbfffe628:48: H
0xbfffe627:58: X
0xbfffe626:59: Y
abcde
0xbfffe629:63: c
0xbfffe628:62: b
0xbfffe627:65: e
0xbfffe626:64: d
ForestDB 2008-05-19
  • 打赏
  • 举报
回复
- -!!!
偶辛辛苦苦打的源码啊...
thorhero 2008-05-19
  • 打赏
  • 举报
回复
正方形转45度,变菱形
这个是某智力题原题

“世纪”必须用在公元后
貌似就是考这个,这两题估计是随便考考缓解下考试紧张气氛的
lixun_21 2008-05-17
  • 打赏
  • 举报
回复
感觉你面试像是 古代建筑学的考试
ONLYBLUEMOON 2008-05-17
  • 打赏
  • 举报
回复
历史学的不好,是不是没有早到 公元前二世纪
正方形转45度,变菱形,你去哪面试了?
zhoujie99 2008-05-17
  • 打赏
  • 举报
回复
是计算机的面试题,大显的原题
ForestDB 2008-05-16
  • 打赏
  • 举报
回复

#include <stdio.h>

typedef unsigned char BYTE;

void print_memory(BYTE *start, int size)
{
int i;

for(i = size - 1; i >= 0; --i) {
printf("%p:%02x: %c\n", start + i, *(start + i), *(start + i));
}
}

int main(void)
{
char ch1 = 'X', ch2 = 'Y';

print_memory(&ch2, 5);
scanf("%3c%2c", &ch1, &ch2);
print_memory(&ch2, 5);
printf("%c, %c\n", ch1, ch2);

return 0;
}

0xbfffdf4a:ff: ÿ
0xbfffdf49:df: ß
0xbfffdf48:68: h
0xbfffdf47:58: X
0xbfffdf46:59: Y
abcde
0xbfffdf4a:ff: ÿ
0xbfffdf49:63: c
0xbfffdf48:62: b
0xbfffdf47:65: e
0xbfffdf46:64: d
e, d

这下就清楚了,其他的依次类推吧.
ForestDB 2008-05-16
  • 打赏
  • 举报
回复

#include <stdio.h>

typedef unsigned char BYTE;

void print_memory(BYTE *start, int size)
{
int i;

for(i = size - 1; i >= 0; --i) {
printf("%p:%02x: %c\n", start + i, *(start + i), *(start + i));
}
}

int main(void)
{
char ch[7] = "XXXXXXX";

print_memory(ch, sizeof(ch));
scanf("%3c%2c", ch, ch + 1);
print_memory(ch, sizeof(ch));
printf("%c, %c\n", *ch, *(ch + 1));

return 0;
}

0xbfffe5b6:58: X
0xbfffe5b5:58: X
0xbfffe5b4:58: X
0xbfffe5b3:58: X
0xbfffe5b2:58: X
0xbfffe5b1:58: X
0xbfffe5b0:58: X
abcde
0xbfffe5b6:58: X
0xbfffe5b5:58: X
0xbfffe5b4:58: X
0xbfffe5b3:58: X
0xbfffe5b2:65: e
0xbfffe5b1:64: d
0xbfffe5b0:61: a
a, d
ForestDB 2008-05-16
  • 打赏
  • 举报
回复
找到了:

man scanf
c Matches a sequence of width count characters (default 1); the
next pointer must be a pointer to char, and there must be enough
room for all the characters (no terminating NUL is added). The
usual skip of leading white space is suppressed. To skip white
space first, use an explicit space in the format.

#include <stdio.h>

typedef unsigned char BYTE;

void print_memory(BYTE *start, int size)
{
int i;

for(i = size - 1; i >= 0; --i) {
printf("%p:%02x: %c\n", start + i, *(start + i), *(start + i));
}
}

int main(void)
{
char ch[7] = "XXXXXXX";

print_memory(ch, sizeof(ch));
scanf("%3c", ch);
print_memory(ch, sizeof(ch));

return 0;
}

0xbffff536:58: X
0xbffff535:58: X
0xbffff534:58: X
0xbffff533:58: X
0xbffff532:58: X
0xbffff531:58: X
0xbffff530:58: X
abcde
0xbffff536:58: X
0xbffff535:58: X
0xbffff534:58: X
0xbffff533:58: X
0xbffff532:63: c
0xbffff531:62: b
0xbffff530:61: a

这个应该是Linux下scanf的实现所规定的吧.
ForestDB 2008-05-16
  • 打赏
  • 举报
回复
关于scanf的是不是看看它的源代码?
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 zhoujie99 的回复:]
不要总关心我的头像啦,只是喜欢的图片而已,嘿嘿

关于scanf的规律,希望高手帮我解释一下

如果是一个编译器未定义,姑且能说过去,但是2个编译器结果一样,他们在处理字符宽度时一定有其根据
[/Quote]
楼主的头像跟过儿的一模一样,哈哈!只是你的是他的放大版,呵呵!
我那天看见这个头像还和过儿说过呢!~
  • 打赏
  • 举报
回复
1.“公元前2世纪”这句话有什么问题?

既然是计算机相关的,我个人认为就是正负的问题,一个标准(基准点)。

2.木匠为财主打造窗户,结果打造出正方形窗户后,财主说“我最讨厌正方形的东西,你要给我改成
其他形状的,但是面积要和现在的窗户一样!”,请问这个木匠应该怎么改?

既然已经打造出窗户了,那“窟窿”已经成形了,不能改小了;改成长的高度高了,所以,定形的东西显然是不能改的了。
只能通过一些装饰品让它显得不那么方。
ForestDB 2008-05-16
  • 打赏
  • 举报
回复
公元前2世纪
这个应该是是考时间点和时间段,基数词和序数词的吧.
zhoujie99 2008-05-16
  • 打赏
  • 举报
回复
这个sizeof的规律实在找不出来就算了,各位高手帮我看看下面的面试问题,答对也有分哦!
是2个真实的面试题:

1.“公元前2世纪”这句话有什么问题?

我刚开始以为“世纪”必须用在公元后,不能用在公元前,但是后来上网一查
在《世界史》--中山大学 第七章 印度的列国时期和孔雀帝国 (公元前6世纪--前2世纪)
看该书上所称,“公元前2世纪”这句话应该没有问题,但是面试到底考什么呢?

2.木匠为财主打造窗户,结果打造出正方形窗户后,财主说“我最讨厌正方形的东西,你要给我改成
其他形状的,但是面积要和现在的窗户一样!”,请问这个木匠应该怎么改?

题目没有其他条件了,所以我个人认为是否改造成圆形或者矩形最好呢?面积相等,并周长小于正方形就可以了,因为财主肯定很抠门,不让木匠再加材料了,木匠自己也不可能买材料来,只能用现有材料,因此假如改成圆形:

圆形面积:3.14*r*r==a*a (a已知,是正方形的边长)
则 r=a /sqrt(3.14) ... 式1
并且 周长: 2*3.14*r<=4*a ... 式2
根据上面 式1 代入 式2 得出 2*3.14*a/sqrt(3.14)<=4*a 去掉a
得2*3.14/sqrt(3.14)<=4 是ok的,所以可以改成圆形

至于矩形还没做,不知这样的思路是否正确?
yeliguo12345 2008-05-10
  • 打赏
  • 举报
回复
不知道,没遇见过,接分
zhoujie99 2008-05-10
  • 打赏
  • 举报
回复
不要总关心我的头像啦,只是喜欢的图片而已,嘿嘿

关于scanf的规律,希望高手帮我解释一下

如果是一个编译器未定义,姑且能说过去,但是2个编译器结果一样,他们在处理字符宽度时一定有其根据
jieao111 2008-05-10
  • 打赏
  • 举报
回复
笑内上也见过此头像,不知道是谁家的孩子
Treazy 2008-05-08
  • 打赏
  • 举报
回复
没啥规律的,这个个人觉得是未定义的行为!
babyvox1999 2008-05-08
  • 打赏
  • 举报
回复
眼熟的头像

70,029

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧