动态获取字符串函数

时间:2013-12-10 22:46:40

标签: c stdin

平台:Windows Vista Home Premium SP2 x86

编译器:MinGW(GCC 4.7.1 tdm-1)(IDE:Code :: Blocks)

我正在编写一个使用相当常见的垃圾收集器循环的函数(getc(stdin)!='\ n')来编写一个动态获取字符串函数,该函数将读取fgets()在标准输入中留下的任何数据呼叫。我正在Windows上编写这个函数,因为我目前无法访问我的电脑,只是为了让你们知道。但我的问题是我希望我的函数dgets()到malloc()一个缓冲区,如果给它的指针是NULL但同时我希望函数返回一个整数。所以我对这个问题的解决方案是一个指向char指针的指针。该函数将被调用。

char *s = NULL;
int n = 0;

if(dgets(&s, &n) != 0) //ERROR

我不经常使用指针指针,所以当我的函数崩溃时我有点困惑。我通过使用以下循环将问题缩小到我解除引用的方式。

char* *s;
int i = 0;

*s = malloc(32);

for(; i < 32; i++) printf("*s[%i] == %c\n", i, *s[i]);

编译并运行上面的代码时,它会崩溃。我的问题是为什么?这是上下文的功能。附:它尚未经过测试,但任何评论都会受到赞赏。

#include <windows.h>
#include <stdio.h>
#include <errno.h>

int dgets(char* *s, size_t *n)
{
    if(n == NULL) return 1;
    if(*n < 0) return 1;
    if(*n == 0) *n = 32;

    if(s == NULL) return 1;
    if(*s == NULL && (*s = malloc(*n)) == NULL) return 1;

    int i = 0;

    for(; i <= *n; i++) *s[i] = 0;

    if(fgets(*s, *n, stdin) == NULL) return 1;

    //Since fgets() will put newlines in the buffer, input is line buffered,
    //and the buffer was initilized to zero if the last element
    //is a nonzero value and not a newline then there must be a newline left
    //in stdin.
    if(*s[*n - 1] != 0 && *s[*n - 1] != '\n')
    {
        i = *n;
        int byte = 0;

        char *tmp = NULL;

        for(; (byte = getc(stdin)) != '\n'; i++)
        {
            if(byte == EOF) return 1;

            if(i == *n)
            {
                //eventually an arbitrary limit will be put here to limit the
                //size of the buffer
                *n *= 2;

                if((tmp = realloc(*s, *n)) == NULL) return 1;

                *s = tmp;
            }

            *s[i] = (char)byte;
        }

        //reallocates the buffer so that it is exact size
        if(*n != i + 2 && (tmp = realloc(*s, i + 2)) == NULL) return 1;

        *s = tmp;
        *n = i + 2;

        *s[i] = (char)byte;
        *s[i + 1] = 0;
    }

    return 0;
}

1 个答案:

答案 0 :(得分:1)

我注意到的两个问题。

  1. 类型不匹配

    int n;
    if(dgets(&s, &n) != 0)
    

    dgets 原型是 int dgets(char ** s,size_t * n)

    &amp; n: int * ,但需要 size_t *

  2. 超出范围的阵列访问&amp;解除引用错误

    for(; i <= *n; i++) *s[i] = 0;
    

    它可以访问保留的外部存储器。

    应该是 i&lt; * n (* s)[i] = 0;

    *s[i]表示*(s[i])

  3. 还需要根据上述更改更改程序的其余部分。