在C中返回while循环内外的值

时间:2014-10-09 11:37:26

标签: c linux while-loop return

我想编写一个程序来读取文件并分解其内容。该文件基本上包含一个包含ID的字符串。该文件的内容如下:

[root@ben-pc ~]# cat file
1,2,3

我想从解析函数中单独返回ID 1,2,3。在我的代码中,我得到while循环中的前两个ID和while循环外的最后一个ID。但我无法正确返回所有这些值。我知道我不能在这样的代码中使用两个return调用。任何人都可以建议我如何根据需要使其工作。这是我的代码:

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

char *get_group_members (char* file)
{
    FILE *fp;
    char *str;
    char filename[64];
    int c;
    size_t n = 0;

    snprintf(filename, sizeof(char) * 64, "/home/ben/%s", file);
    fp = fopen(filename, "r");

    if(fp == NULL)
    {
            perror("Error opening file");
    }

    str = malloc(100);

    while ((c = fgetc(fp)) != EOF )
    {
            if(c != ',')
            {
                    str[n++] = (char) c;
            }
            else
            {
                    //return str; Not working
                    printf("%s,", str);
                    n = 0;
            }
    }
    //return str; Not working
    printf("%s", str);
    fclose(fp);
}

int main (void)
{
printf("Group Members are ::\n");
printf("%s\n", get_group_members("file"));
return 0;
}

1 个答案:

答案 0 :(得分:1)

这里有两个主要选项:返回一个字符串数组,或者进行增量解析。

  • 增量解析:不是在函数中打开文件,而是将已经打开的FILE*传递给它。然后该函数返回下一个成员(作为单个字符串),如果没有,则返回0。 fopen / fclose必须由调用函数管理,用法可能如下所示(错误检查省略):

    FILE *fd = fopen(...);
    char *member;
    while((member = get_member(fd))) {
        // do sth.
    
        free(member);
    }
    fclose(fd);
    

    增量解析的好处是你永远不需要一次将所有返回的数据存储在内存中,你既不需要知道预先返回的元素数量(为它们分配存储),也不需要处理reallocs如果你阅读比预期更多的元素。

    示例实施:

    char *get_group_member (FILE *fp)
    {
        char *str = malloc(100);
        int n = 0;
        int c;
    
        while ((c = fgetc(fp)) != EOF)
        {
            if(c != ',')
            {
                str[n++] = (char) c;
            }
            else
            {
                break;
            }
        }
    
        if(n)
        {
            str[n++] = 0;
            return str;
        }
    
        free(str);
        return 0;
    }
    

    注意:如果任何一个成员超过99个字符,此实现与原始实现一样会遇到缓冲区溢出。

  • 字符串数组:返回char **,其大小为numberOfItems + 1,以0结尾。

    迭代很容易在这样的数组上看起来像这样:

    char ** result = get_members...;
    char *current_member;
    
    while((current_member = result++)) {
        // do something with current_member
    }
    
  • 或者使用两个输出参数,如下所示:

    void get_members_...(char ** result, int *result_size);

    然后分配一个适当大小的数组并相应地设置result_size。

  • 您还可以创建类似链接列表的内容,但这会使结果更加复杂,并且通常需要更多代码。