【问题标题】:How do I store information from a file in to memory in C如何将文件中的信息存储到C中的内存中
【发布时间】:2020-04-12 15:13:54
【问题描述】:

我需要逐行阅读文件并使用从每一行收集的信息进行一些操作。到目前为止,我的代码只能逐行读取文件并在控制台打印。

#include <stdio.h>
#include <stdlib.h>
#include "structure.h"

int main()
{
    printf("Hello world!\n");
    int x = 43; // number of lines in my text file
    FILE *fptr;
    struct values *valuesPtr = malloc(sizeof(struct values) * x);

    if (!valuesPtr)
        return -1;

    if((fptr = fopen("energy.txt", "r")) == NULL) {
        printf ("Error opening file ");
        return 0;
    }

    while (fptr != NULL) {
        for(int i = 0; i < x; i++ ) {
            fscanf(fptr, "%s %s %d", valuesPtr[i].start_vertex, valuesPtr[i].destination_vertex, &valuesPtr[i].num);
            printf("\nStart vertex: %s \nDestination vertex: %s \nWeight: %d\n\n", valuesPtr[i].start_vertex, valuesPtr[i].destination_vertex, valuesPtr[i].num);
        }
        free(valuesPtr);
    }
    fclose(fptr);

    return 0;
}

我的 structure.h 文件有以下代码:

struct values{
    int num;
    char start_vertex[250];
    char destination_vertex[250];
} x;  

energy.txt文件内容如下:

York    Hull    60
Leeds   Doncaster   -47
Liverpool   Nottingham  161
Manchester  Sheffield   61
Reading Oxford  -43
Oxford  Birmingham  103
Birmingham  Leicester   63
Liverpool   Blackpool   79
Carlisle    Newcastle   92
Nottingham  Birmingham  77
Leeds   York    39
Glasgow Edinburgh   74
Moffat  Carlisle    65
Doncaster   Hull    76
Northampton Birmingham  90
Leicester   Lincoln 82
Sheffield   Birmingham  122
Lincoln Doncaster   63
Sheffield   Doncaster   29
Bristol Reading 130
Hull    Nottingham  145
Blackpool   Leeds   116
Birmingham  Bristol 139
Manchester  Leeds   64
Carlisle    Blackpool   140
Leicester   Northampton -61
Newcastle   York    135
Glasgow Moffat  -28
Leicester   Sheffield   100
Carlisle    Liverpool   -30
Birmingham  Manchester  129
Oxford  Bristol 116
Leeds   Hull    89
Edinburgh   Carlisle    154
Nottingham  Sheffield   61
Liverpool   Manchester  56
Carlisle    Glasgow 50
Sheffield   Lincoln 74
York    Doncaster   55
Newcastle   Edinburgh   177
Leeds   Sheffield   53
Northampton Oxford  68
Manchester  Carlisle    20

有人告诉我使用getline() 函数和sscanf() 来存储文件中的数据。但我不确定我应该怎么做。

【问题讨论】:

  • 你得到的建议听起来很合理。阅读 sscanf 函数here
  • 那个链接失效了
  • 已经修复。刷新你的页面(这是关于 Stack Overflow 的那些真正令人讨厌的事情之一,从未被修复过)。
  • 能否详细说明

标签: c linked-list getline


【解决方案1】:

你的代码有几个问题

拥有

    if((fptr = fopen("energy.txt", "r")) == NULL)
    {
        printf ("Error opening file ");
        return 0;
    }
    while (fptr != NULL)

如果 fptr 为 NULL,则无法到达 while,并且 fptr 的值在 while 的主体中永远不会改变,这样一来就是一个无限循环

另一个问题是在 for 之后你释放了 valuesPtr 所以从第二轮开始你将在释放的内存中写入,但内存却是意外的。很可能 while 只是无用的并且可以被删除(但不是 for 当然)。

假设 while 结束你尝试释放 fptr,但这不是关闭描述的方法,你必须调用 fclose(fptr) 而不是 free,你的 free 有一个未定义的行为

我鼓励你检查fscanf返回的值,目前你不知道它是否成功。请注意,fscanf 也可以写出包含字符串的字段,因为您不限制要读取的字符数。

当您无法打开文件时,您可以使用 perror 给出原因:

perror("Error opening file");

修改后的提案:

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

typedef struct value {
  int num;
  char start_vertex[250];
  char destination_vertex[250];
} value;  

int main()
{
  const int nLines = 43; // number of lines in my text file
  FILE * fptr;
  value * valuesPtr = malloc(sizeof(value) * nLines);

  if (!valuesPtr) {
    puts("cannot allocate memory");
    return -1;
  }

  if((fptr = fopen("energy.txt", "r")) == NULL)
  {
    perror("Error opening file");
    return -1;
  }

  for(int i = 0; i < nLines; i++ )
  {
      if (fscanf(fptr, "%249s %249s %d",
                 valuesPtr[i].start_vertex, 
                 valuesPtr[i].destination_vertex, 
                 &valuesPtr[i].num) != 3) {
        printf("errored file line %d\n", i);
        break;
      }

      printf("\nStart vertex: %s \nDestination vertex: %s \nWeight: %d\n\n",
             valuesPtr[i].start_vertex, valuesPtr[i].destination_vertex, valuesPtr[i].num);
  }
  free(valuesPtr);
  fclose(fptr);

  return 0;
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -Wall l.c
pi@raspberrypi:/tmp $ ./a.out

Start vertex: York 
Destination vertex: Hull 
Weight: 60


Start vertex: Leeds 
Destination vertex: Doncaster 
Weight: -47


Start vertex: Liverpool 
Destination vertex: Nottingham 
Weight: 161


Start vertex: Manchester 
Destination vertex: Sheffield 
Weight: 61


Start vertex: Reading 
Destination vertex: Oxford 
Weight: -43


Start vertex: Oxford 
Destination vertex: Birmingham 
Weight: 103


Start vertex: Birmingham 
Destination vertex: Leicester 
Weight: 63


Start vertex: Liverpool 
Destination vertex: Blackpool 
Weight: 79


Start vertex: Carlisle 
Destination vertex: Newcastle 
Weight: 92


Start vertex: Nottingham 
Destination vertex: Birmingham 
Weight: 77


Start vertex: Leeds 
Destination vertex: York 
Weight: 39


Start vertex: Glasgow 
Destination vertex: Edinburgh 
Weight: 74


Start vertex: Moffat 
Destination vertex: Carlisle 
Weight: 65


Start vertex: Doncaster 
Destination vertex: Hull 
Weight: 76


Start vertex: Northampton 
Destination vertex: Birmingham 
Weight: 90


Start vertex: Leicester 
Destination vertex: Lincoln 
Weight: 82


Start vertex: Sheffield 
Destination vertex: Birmingham 
Weight: 122


Start vertex: Lincoln 
Destination vertex: Doncaster 
Weight: 63


Start vertex: Sheffield 
Destination vertex: Doncaster 
Weight: 29


Start vertex: Bristol 
Destination vertex: Reading 
Weight: 130


Start vertex: Hull 
Destination vertex: Nottingham 
Weight: 145


Start vertex: Blackpool 
Destination vertex: Leeds 
Weight: 116


Start vertex: Birmingham 
Destination vertex: Bristol 
Weight: 139


Start vertex: Manchester 
Destination vertex: Leeds 
Weight: 64


Start vertex: Carlisle 
Destination vertex: Blackpool 
Weight: 140


Start vertex: Leicester 
Destination vertex: Northampton 
Weight: -61


Start vertex: Newcastle 
Destination vertex: York 
Weight: 135


Start vertex: Glasgow 
Destination vertex: Moffat 
Weight: -28


Start vertex: Leicester 
Destination vertex: Sheffield 
Weight: 100


Start vertex: Carlisle 
Destination vertex: Liverpool 
Weight: -30


Start vertex: Birmingham 
Destination vertex: Manchester 
Weight: 129


Start vertex: Oxford 
Destination vertex: Bristol 
Weight: 116


Start vertex: Leeds 
Destination vertex: Hull 
Weight: 89


Start vertex: Edinburgh 
Destination vertex: Carlisle 
Weight: 154


Start vertex: Nottingham 
Destination vertex: Sheffield 
Weight: 61


Start vertex: Liverpool 
Destination vertex: Manchester 
Weight: 56


Start vertex: Carlisle 
Destination vertex: Glasgow 
Weight: 50


Start vertex: Sheffield 
Destination vertex: Lincoln 
Weight: 74


Start vertex: York 
Destination vertex: Doncaster 
Weight: 55


Start vertex: Newcastle 
Destination vertex: Edinburgh 
Weight: 177


Start vertex: Leeds 
Destination vertex: Sheffield 
Weight: 53


Start vertex: Northampton 
Destination vertex: Oxford 
Weight: 68


Start vertex: Manchester 
Destination vertex: Carlisle 
Weight: 20

pi@raspberrypi:/tmp $ 

我冒昧地将 values 重命名为 value 因为 struct 保存一个元素而不是多个元素,无论如何我鼓励你重命名它更准确地说,value 是非常笼统的。我还使用了一个 typedef 来不必在每个使用它的地方都需要一个 struct

查看详细信息,例如对于字符串,我使用 %249s 格式,因为数组有 250 个字符(我删除了最后一个空字符的 1),当然我检查它的内容3 个元素。

【讨论】:

  • 好的,我应该如何解决这个问题?
  • 能否给我看一个修改后的代码示例?
  • @UsamaNavid 我已经在我的回答中说过(我编辑了它),我需要知道 values 的定义才能说出所有
  • @UsamaNavid 还提供了 energy.txt 的至少一部分内容,以检查您的 fscanf 是否适用
  • 嘿@bruno 我已经更新了我的问题,我现在想要的是读取每一行并存储每行数据的代码,这些数据可以用于以后在我的算法中进行进一步计算
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-30
  • 2011-10-26
  • 2022-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
相关资源
最近更新 更多