简体   繁体   English

getchar() 在创建字符串数组时不读取空格?

[英]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:为了解决这个问题,将您的声明lengthscanf调用并将其初始化字符串的长度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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM