【问题标题】:Why does getline fail in a C function?为什么 getline 在 C 函数中失败?
【发布时间】:2014-11-04 16:10:35
【问题描述】:

我正在创建一个(非常)基本的 shell - 但是,我是在随意使用函数来更改全局变量的基础上进行的 - 年长和聪明的程序员建议我不要这样做 - 所以我已经着手改变这种行为返回指向变量的指针,而不是更改全局变量。

当我的程序运行 getline 时,读取数据的指针返回空,导致它在我稍后获取字符串的副本时崩溃。我知道 getline 工作正常 - 但是离开方法时结果会丢失。为什么会这样,我该如何解决?

非常感谢!

#define TRUE    1
#define FALSE   0

int readcmd(char* cmd, size_t nBytes);

int argCount = 0; //Counter of number of arguments

int readcmd(char *cmd, size_t nBytes) {

    int ret = getline(&cmd, &nBytes, stdin);

    printf("%s", cmd); //This prints correctly
    return ret;
}

int main() {
    const size_t nBytes = 64; //Data type representing size of objects (unsigned)

    char *cmd = NULL; //Pointer to input string
    char *cmdCpy = NULL;

    int bytesRead = -1;
    char prompt[] = "DaSh-> ";

    while (1) {

        printf("%s", prompt); //Print prompt

        bytesRead = -1;
        while (bytesRead == -1) {
            bytesRead = readcmd(cmd, nBytes); //While no bytes read, loop
        }

        printf("%s", cmd); //This prints "(null)" - data lost!?

        cmdCpy = malloc((sizeof(char) * bytesRead) + 1);
        strcpy(cmdCpy, cmd);

        return 0;
    }
}

【问题讨论】:

    标签: c function pointers getline


    【解决方案1】:

    getline 的调用修改了readcmd 函数的本地cmd 变量。此更改在函数外部不可见,因此当控制返回到main 时,cmd 变量保持不变。 nBytes 变量也是如此。

    要解决这个问题,您可以通过指针将参数传递给readcmd 函数:

    int readcmd(char **cmd, size_t *nBytes) {
        int ret = getline(cmd, nBytes, stdin);
    
        printf("%s", *cmd); //This prints correctly
        return ret;
    }
    
    bytesRead = readcmd(&cmd, &nBytes);
    

    但您不妨直接从main 调用getline 函数。

    【讨论】:

    • 如果ret == -1printf("%s", *cmd); 打印什么?
    • 顺便说一句:您传递nBytes 地址的好建议将导致const size_t nBytes 出现问题,因为不需要size_t nBytes
    • @chux :我认为printf 只是用于调试目的,并将在发布版本中删除。如果不是这种情况,显然,在尝试使用cmd 之前需要检查ret
    • printf 语句让我尝试找出它不起作用的地方!
    【解决方案2】:

    试试这个:

    注意 malloc((sizeof(char) * bytesRead) + 1) if bytesRead == -1

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int readcmd(char **cmd, size_t *nBytes) {
    
        int ret = getline(cmd, nBytes, stdin);
    
        printf("%s", *cmd); //This prints correctly
        return ret;
    }
    
    int main() {
        const size_t nBytes = 64; //Data type representing size of objects (unsigned)
    
        char *cmd = NULL; //Pointer to input string
        char *cmdCpy = NULL;
    
        int bytesRead = -1;
        char prompt[] = "DaSh-> ";
    
        while (1) {
    
            printf("%s", prompt); //Print prompt
    
            bytesRead = -1;
            while (bytesRead == -1) {
                bytesRead = readcmd(&cmd, &nBytes); //While no bytes read, loop
            }
    
            printf("%s", cmd); //This prints "(null)" - data lost!?
    
            cmdCpy = malloc((sizeof(char) * bytesRead) + 1);
            strcpy(cmdCpy, cmd);
    
            return 0;
        }
    }
    

    bytesRead = readcmd(&cmd, &nBytes) 如果要保留数据,则应传递地址。

    【讨论】:

    • 根据linux.die.net/man/3/getline 如果*lineptr 为NULL,那么getline() 将分配一个缓冲区来存储该行,该缓冲区应该由用户程序释放。 (在这种情况下,*n 中的值被忽略。)
    • Grmph,MSVC 没有那些......但你当然是对的!
    【解决方案3】:

    第一次调用 readcmd() 时 cmd 的值为 null 并且没有分配存储因此 getline() 将失败。

    【讨论】:

    • 不应该这样做——据我所知,getline 会自动动态分配内存
    猜你喜欢
    • 1970-01-01
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 1970-01-01
    • 2014-01-22
    相关资源
    最近更新 更多