C: 函数接收到的字符串似乎总是有 4 个空格

标签 c string function parameter-passing

当我练习使用 fgets() 从输入中读取字符串时,我发现自己一遍又一遍地复制同一段代码,因此我创建了一个函数,以便在每次需要时调用。以下是其工作原理的简单示例:

#include <stdio.h>
#include <string.h>

void GetLine(char str[]) {
    // This is the function, I added a printf() to better show what's happening
    printf("Maximum size of the string in GetLine: %i\n", sizeof(str));
    fgets(str, sizeof(str), stdin);

    // This is for clearing the newline character
    // either from the recently received string or from the input buffer
    if (str[strlen(str)-1] == '\n')
        str[strlen(str)-1] = '\0';
    else {
        char DISCARD;
        while((DISCARD = getchar())!='\n' && DISCARD != EOF);
    }
}

int main() {
    char MyString[51];

    printf("Maximum size of the string in main: %i\n", sizeof(MyString));
    GetLine(MyString);

    printf("Contents of the string: >%s<\n", MyString);

    return 0;
}

这是输出:

Maximum size of the string in main: 51
Maximum size of the string in GetLine: 4
My name is Pedro
Contents of the string: >My <

注意如何 str[]只有 4 个空格,而不是传递给它的字符串的大小。

解决这个问题的方法非常简单:make GetLine()还接收一个保存字符串大小的整数,因此它可以读取正确的字符数,而不依赖于 sizeof(str)

但是我真的很想知道为什么会发生这种情况(4 个空格的事情)以及我是否可以以某种方式修复此方法(使 char str[] 与作为参数传递的字符串大小相同)。

提前致谢。

最佳答案

fgets(str, sizeof(str), stdin); 在函数 GetLine 中不正确,因为数组作为指向其第一个元素的指针传递。因此,GetLine() 中的 str 是一个指针,因此 sizeof(str) 不是目标数组的大小,而仅仅是一个指针,在你的系统上占 4 个字节。

您应该将数组的大小传递给 GetLine() 并将其用作 fgets() 的大小参数。

您的代码中还存在其他问题:

  • 您应该测试 fgets() 的返回值以正确检测文件结尾。

  • 您应该将 DISCARD 设为 int,以便它可以正确存储 EOF

  • 您使用一种低效且稍微不正确的方法丢弃缓冲区末尾的换行符:strlen(str) 极有可能是0 。你可以使用这个衬垫:

    str[strcspn(str, "\n")] = '\0';  // discard the newline if present.
    

    或者您可以使用strchr()

这是更正后的版本:

#include <stdio.h>
#include <string.h>

char *GetLine(char str[], int size) {
    if (fgets(str, size, stdin)) {
        char *p = strchr(str, '\n');
        if (p != NULL) {
            // This is for clearing the newline character
            *p = '\0';
        } else {
            int c;
            while ((c = getchar()) != EOF && c != '\n')
                continue;
        }
        return str;
    }
    return NULL;
}

int main(void) {
    char MyString[51];

    printf("Maximum size of the string in main: %i\n", (int)sizeof(MyString) - 1);
    if (GetLine(MyString, sizeof(MyString)))
        printf("Contents of the string: >%s<\n", MyString);

    return 0;
}

关于C: 函数接收到的字符串似乎总是有 4 个空格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47045313/

相关文章:

javascript - 如何将日期显示为字符串?

损坏的 ints 和 sscanf——以及其他与 C 相关的内存问题

c - 函数 srand、rand 和 system 的隐式声明

c - 我如何将结构指针数组中的结构直接复制到c中的另一个结构

在 C 编程中使用等号比较字符串

java - 字符串和 StringBuffer

php - 在执行函数之前检查sql中的日期时间

c++ - 使用断言参数存在的参数化类创建。使用工厂?

function - 将函数的返回值分配给 unix shell 脚本中的变量

c - 为什么使用 argv[] 调用 sscanf() 只能使用一次?