【问题标题】:fscanf specific digits from a filefscanf 文件中的特定数字
【发布时间】:2016-01-14 20:21:19
【问题描述】:

所以我得到了这个文件,我只想scanf() 第一个{} 中的数字而不是第二个{} 中的数字等等。 我设法只调用文件中的数字,但我不知道如何将它们分成组

这是文件:

{5, 2, 3}, {1,5}, { }, { }, {3}, { }, { }

下面是我目前使用的代码

    void main()
{
    int rc=0,num,size;
    FILE* f = fopen("graph-file.txt","rt");
    if (f == NULL)
    {
        printf("Failed to open the file\n");
    }
    size = fscanf(f,"%d",&num);
    fseek(f,1,SEEK_CUR);
    while(rc != EOF)
    {
            if( rc == 1)
            {
                printf("%d\n",num);
            }
            fseek(f,1,SEEK_CUR);
        rc = fscanf(f,"%d",&num);

    }
}

【问题讨论】:

  • 你是怎么学的fscanf()?这段代码是错误的,例如不能保证rcfscanf() 第一次失败时会是EOF
  • if( ch =='{') 正在测试一个未初始化的变量,该变量甚至没有被随后设置。
  • 如果对@WeatherVane 有帮助,我会把整个代码放在上面,我没有注意到这一行,我删除了它
  • 所以您在 20 多行代码中苦苦挣扎,以至于您甚至没有注意到您不使用的变量?顺便说一句,它应该是int main(void)
  • 您确定 JSON 库不是更好的选择吗?如果做不到这一点,那么它看起来像'read line;流程线,不一定只使用sscanf()' 将是一种明智的方法,可以更轻松地跳过{}

标签: c file scanf


【解决方案1】:

您的代码存在一些问题,例如模式字符串错误"rt"?您只需要为二进制指定"b",这只会影响行尾字符,如果文件在不同平台上读取/写入,这可能会出现问题。

要实现你想要的没有简单的方法,正如@JonathanLeffler 建议in this comment 你可以使用一个jsonjson-c1 是一个非常易于使用。

如果你想自己做,试试我刚刚写的这段代码

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

int
append_number(int size, int **arrays, int value)
{
    void *pointer;

    pointer = realloc(arrays[0], (++size + 1) * sizeof(**arrays));
    if (pointer == NULL)
        return 0;
    arrays[0] = pointer;
    arrays[0][size] = value;

    return 1;
}

int
get_value(const char *input)
{
    if (input == NULL)
        return -1;
    while ((*input != '\0') && (isspace((unsigned char) *input) != 0))
        input++;
    if (*input == '\0')
        return -1;
    return atoi(input);
}

int *
extract_arrays(char *array)
{
    int value;
    int *list;
    list = malloc(sizeof(*list));
    if (list == NULL)
        return NULL;
    list[0] = 0;
    while (array != NULL)
    {
        char *delimiter;

        delimiter = strchr(array, ',');
        if (delimiter != NULL)
            *delimiter = '\0';
        value = get_value(array);
        if (value > 0)
            list[0] += append_number(list[0], &list, value);
        if (delimiter != NULL)
            array = delimiter + 1;
        else
            array = NULL;
    }

    return list;
}

void
print_array(int *list)
{
    fprintf(stdout, "[");
    for (int j = 1 ; j < list[0] ; ++j)
        fprintf(stdout, "%d ", list[j]);
    if (list[0] > 0)
        fprintf(stdout, "%d", list[list[0]]);
    fprintf(stdout, "]\n");
}

int **
parse_line(char *line, size_t *count)
{
    char *open;
    char *close;
    char *next;
    int **arrays; // Depends on the maximum size of an inner array

    *count = 0;
    arrays = NULL;
    next = line;

    while ((next != NULL) && ((open = strchr(next, '{')) != NULL))
    {
        close = strchr(open, '}');
        if (close != NULL)
        {
            void *pointer;
            char *values;

            *close = '\0';
            next = strchr(close + 1, ',');
            values = open + 1;
            pointer = realloc(arrays, (*count + 1) * sizeof(*arrays));
            if (pointer == NULL)
                goto error;
            arrays = pointer;

            arrays[(*count)++] = extract_arrays(values);
        }
        else
            next = open + 1;
    }
    return arrays;
error:
    for (size_t i = 0 ; i < *count ; ++i)
        free(arrays[i]);
    free(arrays);
    *count = 0;
    return NULL;
}

int main(void)
{
    char line[100];
    size_t count;
    int **arrays;
    FILE *file;

    file = fopen("graph-file.txt", "r");
    if (file == NULL)
        return -1; // Failure openning the file
    while (fgets(line, sizeof(line), file) != NULL)
    {
        arrays = parse_line(line, &count);
        for (size_t i = 0 ; i < count ; ++i)
        {
            print_array(arrays[i]);
            // DO something with it ...
            free(arrays[i]);
        }
        free(arrays);
    }
    fclose(file);
    return 0;
}

当然,有很多可能的优化(特别是 realloc() 部分),但我留给你。

上面,parse_line() 返回的int ** 指针包含count 数组,其中第一个元素是每个数组的长度。


1我知道在大多数 linux 发行版上都可以使用包管理器安装它,而且我最近在一些与 Web 开发相关的项目中经常使用它。

【讨论】:

    【解决方案2】:

    数组可能是您完成这项任务所需要的。数组允许你有不同数量的数字,你可以存储你读到的内容。这就是您可以分离分组的方式。下一部分将是如何更改您正在查看的数组的哪一部分,这个链接也应该有所帮助。 C Arrays Tutorial.

    如果您尝试读取的数字只是个位数,那么您可以放弃 fseek 和 fscanf 函数并改用 getc。只需检查每个读数是否有任何不是数字“0”-“9”的内容。 C getc

    我链接的那些网站也有很多其他学习 C\C++ 的好教程。

    祝你好运。 编辑:不那么居高临下。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-27
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      • 2019-03-12
      • 2017-06-25
      • 2014-02-10
      • 1970-01-01
      相关资源
      最近更新 更多