[英]getchar() is not reading spaces when creating string array?
I am trying to create a reversed string using getchar() to first read a string in array format.我正在尝试使用 getchar() 创建一个反向字符串,以首先读取数组格式的字符串。 I did not write the reversing part yet.
我还没有写反转部分。 The code works for any strings without space.
该代码适用于任何没有空格的字符串。 Ex.
前任。 "HelloWorld!"
“你好,世界!” will output "HelloWorld!"
将输出“HelloWorld!” but "Hello World!"
但是“世界你好!” will only output "Hello".
只会输出“你好”。
#include <stdio.h>
#define MAX_SIZE 100
int main()
{
char temp;
char my_strg[MAX_SIZE];
int length;
printf("Please insert the string you want to reverse: ");
scanf("%s", my_strg);
while((temp = getchar()) != '\n')
{
my_strg[length] = temp;
length++;
}
printf("%s\n", my_strg);
return 0;
}
Your issue is scanf
.你的问题是
scanf
。 scanf
only reads until whitespace is encountered. scanf
只读取直到遇到空格。 To fix this, you can use fgets
(and strcspn
to remove the newline):要解决此问题,您可以使用
fgets
(和strcspn
删除换行符):
if(fgets(my_strg, sizeof(my_strg), stdin) == NULL)
{
perror("fgets");
return EXIT_FAILURE;
}
my_strg[strcspn(my_strg, "\n")] = '\0';
Or with scanf
...或者用
scanf
...
if(scanf("%99[^\n]", my_strg) != 1)
{
fprintf(stderr, "scanf() failed to read\n");
return EXIT_FAILURE;
}
After these changes you can entirely remove your getchar
loop.在这些更改之后,您可以完全删除
getchar
循环。
In your program you need to check for I/O errors.在您的程序中,您需要检查 I/O 错误。 I've shown you how to do this above.
我已经向您展示了如何做到这一点。 If you don't do this, your program could give incorrect output or in certain cases cause undefined behavior (which usually results in a crash).
如果您不这样做,您的程序可能会给出不正确的输出,或者在某些情况下会导致未定义的行为(通常会导致崩溃)。
Bonus: here's how to reverse a string:奖励:这是反转字符串的方法:
size_t l = strlen(my_strg) / 2;
char *s = my_strg, *e = s + l;
while(l--)
{
char tmp = *--e;
*e = *s;
*s++ = tmp;
}
Your program has undefined behaviour , since you are attempting to access an element of an array, my_strg[length]
with an unitialized value of length
.程序具有未定义的行为,因为你试图访问的阵列,的元素
my_strg[length]
与一个未初始化值length
。
To fix this, move your declaration of length
to after the scanf
call and initialize it to the length of the string that scanf
reads:为了解决这个问题,将您的声明
length
到后scanf
调用并将其初始化字符串的长度scanf
如下:
scanf("%s", my_strg);
size_t length = strlen(my_strg);
Alternatively, drop the scanf
call completely and initialize length
to zero:或者,完全放弃
scanf
调用并将length
初始化为零:
char my_strg[MAX_SIZE] = { 0, }; // Note: make sure you ALSO initialize your array!!
printf("Please insert the string you want to reverse: ");
size_t length = 0;
while ((temp = getchar()) != '\n') {
//..
Note: If you (for some reason) don't want to initialize your entire array to zeros (as the first line in my second code block will do), then make sure to add a zero ( nul
) character at the end of the string, before printing it (or doing anything else with it).注意:如果您(出于某种原因)不想将整个数组初始化为零(就像我的第二个代码块中的第一行那样),请确保在末尾添加一个零 (
nul
) 字符字符串,在打印它之前(或用它做任何其他事情)。 You could simply add this line after the while
loop:您可以在
while
循环后简单地添加这一行:
my_strg[length] = '\0'; // "length" will already point to one-beyond-the-end
EDIT: To address the very good points made by David C. Rankin in the comments section, you could (should) improve your while
loop control to: (a) prevent buffer overflow and (b) handle input error conditions.编辑:为了解决David C. Rankin在评论部分提出的非常好的观点,您可以(应该)改进您的
while
循环控制以:(a)防止缓冲区溢出和(b)处理输入错误条件。 Something like this:像这样的东西:
while ((length < MAXSIZE - 1) && (temp = getchar()) != '\n' && temp != EOF) {
//..
but the exact tests and controls you use would depend on how you wish to handle such issues.但是您使用的确切测试和控制将取决于您希望如何处理此类问题。
By definition, scanf("%s", my_strg)
reads a string until the first white space (and a blank counts as white space).根据定义,
scanf("%s", my_strg)
读取字符串直到第一个空格(空格算作空格)。 So "Hello world"
will be read until the first blank, ie my_strg
will contain "Hello"
then.所以
"Hello world"
将被读取到第一个空白,即my_strg
将包含"Hello"
。 To read until a new line (including the newline), use fgets
.要读取到新行(包括换行符),请使用
fgets
。
BTW: variable length
is uninitialized, such that you get undefined behaviour.顺便说一句:可变
length
未初始化,因此您会获得未定义的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.