【问题标题】:Read a file containing an array of long in C在 C 中读取包含 long 数组的文件
【发布时间】:2015-01-04 05:06:20
【问题描述】:

我正在尝试从我刚刚创建的 long 数组中获取数据,但我得到了不同的数据。

请看下面的代码:

#include <string.h>
#include "readfile.h"

int main()
{

long  wr_data [6] ;
wr_data[0] = 11;
wr_data[1] = 1100;
wr_data[2] = 1122323;
wr_data[3] = 11333;
wr_data[4] = 11434243;
wr_data[5] = 1166587;
writeFile(wr_data);
readFile();

return(0);
}

int readFile()
{
 FILE *file;
long * data 

printf("Error Reading File\n");;

/* Open file for both reading and writing */
file = fopen(fileName, "r");

if (file == NULL)
{
    printf("Error Reading File\n");
     return -1;
}

for (int i = 0; i < 5; i++)
{
    fscanf(file, "%ld", &data[i] );
    printf("data[%d]: %ld \n",i, data[i]);
}
fclose(file);
return 0;
}

int writeFile(long * data)
{
FILE *fp;


if (data != NULL)
{
if ((fp = fopen(fileName,"w")) == NULL)
    return -1;
if (*data !=0 )
    fwrite(data,sizeof(long),6,fp);

printf("Write data\n");
fclose(fp);
}
return 0;
}

我得到的结果如下:

  • 写入数据
  • 数据[0]:140526045102081
  • 数据[1]:47
  • 数据[2]:197764
  • 数据[3]:140526045102080
  • 数据[4]: 4096

我想保留 write 函数,因为它来自现有代码。我也尝试了函数 fread 但没有成功

  fread(data, sizeof(long ), 6, file);

提前感谢您的帮助。

【问题讨论】:

  • 什么操作系统?该代码是不可移植的。
  • long *data;
  • @Jasen:对我来说,UB 似乎相当便携。
  • @PeterSchneider 二进制数据文件应以“wb”而不是“w”模式打开
  • 不确定为什么有人要运行非 posix 系统,但手册页说“模式字符串还可以包含字母 'b' 作为最后一个字符或作为上面描述的任何两个字符串中的字符。这严格是为了与 C8​​9 兼容并且没有任何影响;在所有符合 POSIX 的系统(包括 Linux)上都会忽略“b”。(其他系统可能会以不同的方式处理文本文件和二进制文件, 如果您对二进制文件执行 I/O 并希望您的程序可以移植到非 UNIX 环境,则添加 'b' 可能是个好主意。)"

标签: c fopen readfile fread scanf


【解决方案1】:

它在这里工作。我对您的代码进行了以下更改:

//needed for malloc
#include <stdio.h>
//needed for output
#include <stdlib.h>

...

char *fileName = "so";

...

//allocate memory to store the values
long *data = (long *)malloc(sizeof(long)*6);

...

//read the stored longs
fread(data, sizeof(long ), 6, file);
int i;
for(i=0; i<6; i++)
    printf("%ld\n", data[i]);

你怎么看?

编辑: 那么主要的变化是内存分配。当您想要存储任何类型的值时,您的程序需要由操作系统授予一个内存区域来存储这些值。

在这种情况下,我们有两个选择,要么创建一个具有固定大小的静态分配数组,要么使用 malloc 函数或等效函数以动态方式分配所需的内存。

不要忘记,如果你想存储一些东西,首先要确保你有一个地方可以存储它(即分配的内存)。如果你不这样做,你很可能会收到一个错误“Segmentation Fault”又名“SIGSEGV”,这意味着你试图访问不属于你的内存。

另外,“fscanf(file, "%ld", &data[i] );"将“文件”作为文本读取,并尝试从相同的文本中解析浮点数。由于您将 longs 存储为 longs 而不是文本,因此这是行不通的,因为您正在编写和阅读不同的内容。

【讨论】:

  • 您可以强调并解释更多您所做的事情(您还修复了我最初没有发现的数据的原始文本读取)。
  • 谢谢Bernardo,我来自java世界,我没有意识到内存分配的必要性。但你的解释很好。非常感谢:)
【解决方案2】:

您正在将数组的二进制内容写入文件,然后尝试将其解释为显然无法工作的 long 值。如果要将数字存储为文本,则必须在写入之前将它们转换为文本,或者使用 fprintf(FILE *, const char *, ...) 函数将它们打印到文件中。

使用以下代码使用文本文件(您可能想要更改文件名)按预期工作。否则,您可以只使用 fwritefread 整个内容,具体取决于您的需要。

#include <stdio.h>
const char *filename = "yourfile";

int readFile()
{
    FILE *file;
    long data[6];
    int i;

    printf("Error Reading File\n");;

    /* Open file for both reading and writing */
    file = fopen(filename, "r");

    if (file == NULL)
    {
        printf("Error Reading File\n");
        return -1;
    }

    for (i = 0; i < 6; i++)
    {
        fscanf(file, "%ld", &data[i] );
        printf("data[%d]: %ld \n",i, data[i]);
    }
    fclose(file);
    return 0;
}

int writeFile(long * data)
{
    FILE *fp;
    int i;

    if (data != NULL)    
    {
        if ((fp = fopen(filename,"w")) == NULL)
            return -1;

        if (*data !=0 )
        {
            for(i = 0; i != 6; ++i)
                fprintf(fp, "%ld ", data[i]);       
        }       

        printf("Write data\n");
        fclose(fp);
    }

    return 0;
}

int main()
{

    long  wr_data [6] ;
    wr_data[0] = 11;
    wr_data[1] = 1100;
    wr_data[2] = 1122323;
    wr_data[3] = 11333;
    wr_data[4] = 11434243;
    wr_data[5] = 1166587;
    writeFile(wr_data);
    readFile();

    return(0);
}

【讨论】:

  • 感谢您的快速回答!!!两种解决方案都运作良好。供您参考,我已在 mac os 下编译并运行该程序。
猜你喜欢
  • 2014-01-26
  • 1970-01-01
  • 2021-02-04
  • 1970-01-01
  • 2013-10-26
  • 1970-01-01
  • 1970-01-01
  • 2015-05-20
  • 2015-05-14
相关资源
最近更新 更多