2011-11-07 77 views
3

可能重复:
How do you allow spaces to be entered using scanf?scanf(%s)不允许空间? C编程

char inputStr[64]; 
int inputInt; 
printf("Enter a number:"); 
scanf("%d",&inputInt); 
printf("\nEnter a string:"); 
scanf("%s",&inputStr); 

上面的代码具有2部分,在读整数和字符串。

读取一个整数很好。

读取字符串也很好,考虑到字符在64以下,并且没有空格。

这就是问题所在。

scanf只能读取字符到一个空格。

空间消失后的一切。

如何在scanf中包含空间?

回答

1

而不是使用scanf("%s", ...),使用方法:

fgets(inputStr, 64, stdin) 

这是更好的做法,因为它是不容易出现缓冲区溢出攻击,它会在输入的整条生产线,这似乎你”读重新尝试去做。请注意,换行符\n在使用fgets时也会读入缓冲区(假设整行符合缓冲区)。

此外,将数组传递给函数时,你与你的第二个电话scanf做,你不需要使用运营商(&)地址的。数组的名称(即inputStr数组的起始地址。

+0

是的,tkz很多。 'fgets'读取空格。但它也读取'\ n'。我怎么忽略它? – william

+0

@william你总是可以通过:'inputStr [strlen(inputStr) - 1] ='\ 0'来移除'\ n';'如果字符串中的最后一个字符是''\ n''。 – AusCBloke

+1

@william只要将\ n更改为\ 0我猜。 –

2

如果您想要读取一行代替,请改用fgets(gets is unsafe)。

fgets(inputStr, 64, stdin) 
+1

+1或者'scanf(“%63 [^ \ n]”);' – cnicutar

+0

@cnicutar虽然我真的想要建议很难读懂某些人,所以我没有实际使用它在生产代码一段时间,并倾向于避免它。但我肯定会+1作为答案:) –

+0

@cnicutar - 虽然这将工作,结合这一点,并使更复杂的'scanf'格式说明符的诱惑太大,在这种情况下错误恢复太困难。我宁愿每天都用'fgets' /'sscanf'而不是普通的'scanf'(或'fscanf')。 –

0

Jesus has the answer -- switch to fgets(3);如果你很好奇,为什么你不能scanf(3)捕捉空白:

s  Matches a sequence of non-white-space characters; the 
      next pointer must be a pointer to character array that 
      is long enough to hold the input sequence and the 
      terminating null character ('\0'), which is added 
      automatically. The input string stops at white space 
      or at the maximum field width, whichever occurs first. 
1

如果你想继续使用scanf函数(例如,如果此字符串只是一些你与scanf函数读取输入的),你可以考虑使用“扫描集”的转换,如:

scanf("%63[^\n]%*c", inputStr); 

不像fgets,这并不在字符串中包含尾随新行看完之后。还要注意,使用scanset转换,您指定要读取的字符串的最大长度而不是缓冲区大小,因此您需要指定一个小于缓冲区大小的字符串,以便为终止NUL留出空间。

我已经包含了“%* c”来读取,但放弃了新行。新行被认为是空白,在scanf转换字符串中特别对待。普通字符只会匹配并忽略输入中的那个字符,但是空白匹配并忽略连续的空格全部。这与交互式输入特别讨厌,因为这意味着空白转换不会完成匹配,直到你输入一些东西其他即表示空白。

+0

使用'“%* c”'可能很糟糕 - 如果用户键入的字符数超过63个,则会丢弃最后一个字符(认为它是换行符)。你可以做''%* [\ n]“',但是你仍然必须使用'scanf'奇妙的(读取:可怕的)错误检查机制来查看它是否确实如此,实际上是注册一个换行符,或者如果还有更多待定的用户输入。 –

+0

@ChrisLutz:的确如此。大多数人只是无视这种额外的东西(或将其视为错误),但如果您希望*(例如)扩大您的分配范围并在输入更多内容时阅读更多内容,使用scanf比使用fgets更容易:'scanf (%63 [^ \ n]%c“,inputStr,&someChar); if(someChar!='\ n')read_more();' –