创建字符串数组时 getchar() 不读取空格?
getchar() is not reading spaces when creating string array?
我正在尝试使用 getchar() 创建一个反转字符串,以首先读取数组格式的字符串。我还没有写反转部分。该代码适用于没有 space 的任何字符串。
前任。 "HelloWorld!" 会输出 "HelloWorld!" 但 "Hello World!" 只会输出 "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;
}
根据定义,scanf("%s", my_strg)
读取字符串直到第一个白色 space(空白算作白色 space)。所以 "Hello world"
将被读取到第一个空白,即 my_strg
将包含 "Hello"
然后。要阅读到新行(包括换行符),请使用 fgets
.
顺便说一句:变量 length
未初始化,因此您会得到未定义的行为。
您的问题是 scanf
。 scanf
只读取直到遇到空格。要解决此问题,您可以使用 fgets
(和 strcspn
删除换行符):
if(fgets(my_strg, sizeof(my_strg), stdin) == NULL)
{
perror("fgets");
return EXIT_FAILURE;
}
my_strg[strcspn(my_strg, "\n")] = '[=10=]';
或 scanf
...
if(scanf("%99[^\n]", my_strg) != 1)
{
fprintf(stderr, "scanf() failed to read\n");
return EXIT_FAILURE;
}
进行这些更改后,您可以完全删除 getchar
循环。
在您的程序中,您需要检查 I/O 错误。我已经在上面向您展示了如何执行此操作。如果不这样做,您的程序可能会给出不正确的输出,或者在某些情况下会导致未定义的行为(通常会导致崩溃)。
奖励:这是反转字符串的方法:
size_t l = strlen(my_strg) / 2;
char *s = my_strg, *e = s + l;
while(l--)
{
char tmp = *--e;
*e = *s;
*s++ = tmp;
}
你的程序有未定义的行为,因为你正试图访问一个数组的元素,my_strg[length]
使用unitialized length
的值。
要解决此问题,请将 length
的声明移动到 之后 scanf
调用并将其初始化为 [=17] 的字符串的长度=] 读取:
scanf("%s", my_strg);
size_t length = strlen(my_strg);
或者,完全放弃 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') {
//..
注意:如果您(出于某种原因)不想将整个数组初始化为零(就像我的第二个代码块中的第一行那样),那么请确保添加一个零 (nul
) 字符串末尾的字符,然后打印它(或用它做任何其他事情)。您可以简单地在 while
循环 之后添加此行:
my_strg[length] = '[=12=]'; // "length" will already point to one-beyond-the-end
编辑:为了解决 David C. Rankin 在评论部分提出的非常好的观点,您可以(应该)改进您的 while
循环控制以:(a)防止缓冲区溢出和(b ) 处理输入错误情况。像这样:
while ((length < MAXSIZE - 1) && (temp = getchar()) != '\n' && temp != EOF) {
//..
但您使用的确切测试和控制将取决于您希望如何处理此类问题。
我正在尝试使用 getchar() 创建一个反转字符串,以首先读取数组格式的字符串。我还没有写反转部分。该代码适用于没有 space 的任何字符串。 前任。 "HelloWorld!" 会输出 "HelloWorld!" 但 "Hello World!" 只会输出 "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;
}
根据定义,scanf("%s", my_strg)
读取字符串直到第一个白色 space(空白算作白色 space)。所以 "Hello world"
将被读取到第一个空白,即 my_strg
将包含 "Hello"
然后。要阅读到新行(包括换行符),请使用 fgets
.
顺便说一句:变量 length
未初始化,因此您会得到未定义的行为。
您的问题是 scanf
。 scanf
只读取直到遇到空格。要解决此问题,您可以使用 fgets
(和 strcspn
删除换行符):
if(fgets(my_strg, sizeof(my_strg), stdin) == NULL)
{
perror("fgets");
return EXIT_FAILURE;
}
my_strg[strcspn(my_strg, "\n")] = '[=10=]';
或 scanf
...
if(scanf("%99[^\n]", my_strg) != 1)
{
fprintf(stderr, "scanf() failed to read\n");
return EXIT_FAILURE;
}
进行这些更改后,您可以完全删除 getchar
循环。
在您的程序中,您需要检查 I/O 错误。我已经在上面向您展示了如何执行此操作。如果不这样做,您的程序可能会给出不正确的输出,或者在某些情况下会导致未定义的行为(通常会导致崩溃)。
奖励:这是反转字符串的方法:
size_t l = strlen(my_strg) / 2;
char *s = my_strg, *e = s + l;
while(l--)
{
char tmp = *--e;
*e = *s;
*s++ = tmp;
}
你的程序有未定义的行为,因为你正试图访问一个数组的元素,my_strg[length]
使用unitialized length
的值。
要解决此问题,请将 length
的声明移动到 之后 scanf
调用并将其初始化为 [=17] 的字符串的长度=] 读取:
scanf("%s", my_strg);
size_t length = strlen(my_strg);
或者,完全放弃 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') {
//..
注意:如果您(出于某种原因)不想将整个数组初始化为零(就像我的第二个代码块中的第一行那样),那么请确保添加一个零 (nul
) 字符串末尾的字符,然后打印它(或用它做任何其他事情)。您可以简单地在 while
循环 之后添加此行:
my_strg[length] = '[=12=]'; // "length" will already point to one-beyond-the-end
编辑:为了解决 David C. Rankin 在评论部分提出的非常好的观点,您可以(应该)改进您的 while
循环控制以:(a)防止缓冲区溢出和(b ) 处理输入错误情况。像这样:
while ((length < MAXSIZE - 1) && (temp = getchar()) != '\n' && temp != EOF) {
//..
但您使用的确切测试和控制将取决于您希望如何处理此类问题。