任何人都可以解释我这个功能是如何工作的?

时间:2017-06-29 06:49:04

标签: c string function

我不明白这个功能是做什么的。有人可以详细解释一下吗?

char *my_getline(FILE *stream) {
    char *line = NULL;
    size_t pos = 0;
    int c;

    while ((c = getc(stream)) != EOF) {
        char *newp = realloc(line, pos + 2);
        if (newp == NULL) {
            free(line);
            return NULL;
        }
        line = newp;
        if (c == '\n')
            break;
        line[pos++] = (char)c;
    }
    if (line) {
        line[pos] = '\0';
    }
    return line;
}

如果您可以在我的代码上添加评论,我认为这对我有帮助。我想在字符串中搜索子字符串,然后找到了这个函数代码。

这是主要功能:

int main(void) {
    char *str, *sub;
    size_t len1, len2, i, count = 0;
    printf("Insert string :\n");
    str = my_getline(stdin);
    printf("insert substring :\n");
    sub = my_getline(stdin);

    if (str && sub) {
        len1 = strlen(str);
        len2 = strlen(sub);
        for (i = 0; i + len2 <= len1; i++) {
            if (!memcmp(str + i, sub, len2)) {
                count++;
                printf("Substring found at index : %d\n", i);
            }
        }
        printf("in the number of: %d\n", count);
        if (count == 0) {
            printf("Substring not found\n");
        }
    }
    free(str);
    free(sub);
    return 0;
}

我理解主函数但无法理解函数my_getline中的逻辑。

请帮助我理解逻辑。谢谢!

2 个答案:

答案 0 :(得分:1)

char *my_getline(FILE *stream) {
    // pointer to the line to be read:
    char *line = NULL;
    // position of the next character:
    size_t pos = 0;
    // single character:
    int c;

    while ((c = getc(stream)) != EOF) { // read 1 character at a time until EOF
        // allocate a new buffer with room for the char just read + a 0 terminator
        // when `line` is NULL, this is the same as `malloc()`, otherwise it 
        // will change the size of the allocation:
        char *newp = realloc(line, pos + 2);

        // check for errors:
        if (newp == NULL) {
            free(line);
            return NULL;
        }

        // no errors, assign new buffer to `line`:
        line = newp;

        // end of line found: we're done:
        if (c == '\n')
            break;

        // otherwise add new character to the line:
        line[pos++] = (char)c;
    }

    // if there was *anything* to read, add 0 terminator (marks end of string):
    if (line) {
        line[pos] = '\0';
    }
    return line;
}

就是这样。请注意它的效率非常低有两个原因:它一次只读取一个字符,并为每个字符调用realloc()

更好的解决方案是使用例如fgets()并以合理的块增加缓冲区大小,例如:

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

#define GETLINE_CHUNK 1024

static void xrealloc(void *bufPtr, size_t size)
{
    void **buf = bufPtr;
    void *tmp = realloc(*buf, size);
    if (!tmp)
    {
        free(*buf);
        *buf = 0;
    }
    *buf = tmp;
}    

char *my_getline(FILE *stream)
{
    // allocate first chunk:
    char *buf = malloc(GETLINE_CHUNK);
    if (!buf) return 0;
    *buf = 0;
    size_t pos = 0;

    // read up to GETLINE_CHUNK bytes, until newline:
    while (fgets(buf + pos, GETLINE_CHUNK, stream))
    {
        // look for newline:
        char *nlPos = strchr(buf, '\n');
        if (nlPos)
        {
            // found, then our line is complete
            *nlPos = 0;

            // shrink buffer to needed size
            xrealloc(&buf, nlPos-buf+1);
            return buf;
        }

        // set next offset to read
        pos = strlen(buf);

        // increase buffer size to have room for a whole other GETLINE_CHUNK:
        xrealloc(&buf, pos + GETLINE_CHUNK);
        if (!buf) return 0;
    }

    // if nothing was read, free buffer and return NULL:
    if (*buf == 0)
    {
        free(buf);
        buf = 0;
    }
    return buf;
}

int main(void)
{
    char *line = my_getline(stdin);
    if (line)
    {
        puts(line);
        free(line);
    }
    else puts("no input!");
    return 0;
}

答案 1 :(得分:0)

这个功能为你提供了线路,让我们一步一步走:

char *my_getline(FILE *stream) {
    char *line = NULL; //this is just pointer initialization
    size_t pos = 0; //position variable definition and init 
    int c; //a variable to store temporary character

    while ((c = getc(stream)) != EOF) //read every character till end of file  
    {
        // To dynamically allocate memory, with reference to the 
        // number of character and plus '2' is just to compensate null
        // character and the character(Since pos is 0)

        char *newp = realloc(line, pos + 2); 

        if (newp == NULL) { // this is to check whether memory was alloacted properly or not.  
            free(line); //if not free line 
            return NULL;// break the program and return NULL
        }

        line = newp;// if memory is allocated properly store allocated memory in line pointer

        if (c == '\n') //if new line is detected
            break;// break the while loop
        line[pos++] = (char)c; // store the character in dynamically allocated memory and new character in new location.
    }

    if (line) { //if line contains something then add a null character at last, to complete that string
        line[pos] = '\0';
    }

    return line; //returns the content of line.
}

希望这会有所帮助:)