【问题标题】:How do I write 2D-array to file using C?如何使用 C 将二维数组写入文件?
【发布时间】:2016-02-24 01:24:04
【问题描述】:

我正在尝试编写一个程序,该程序必须将 ASCII 图片(每行具有不同的长度)存储在 2D 数组中,然后再次打印出来。要么我必须在“\n”处剪切数组,要么我必须创建一个动态大小的数组。这是我到目前为止所拥有的。它以正确的方式打印出来,但每行有 255 个字符。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_LENGTH 255

int main(void) {
    FILE *iFile, *oFile;
    char elements[MAX_LENGTH][MAX_LENGTH];
    memset(elements, 0, MAX_LENGTH);
    int zeile = 0, position = 0, size = 0;
    char c;
    bool fileend = false;

    //open files
    iFile = fopen("image.txt", "r");
    oFile = fopen("imagerotated.txt", "w+");

    if ((iFile == NULL) || (oFile == NULL))
    {
        perror("Error: File does not exist.");
        exit(EXIT_FAILURE);
    }


    //read File to a 2D-Array
    while (1) {
        if ((c = fgetc(iFile)) != EOF) {
            if (c == '\n') {
                zeile++;
                position = 0;
            }
            elements[zeile][position] = c;
            position++;
        }
        else {
            fileend = true;
        }

        if (fileend == true) {
        break;
        }
    }

    //Write 2D-Array into the output file
    fwrite(elements, MAX_LENGTH, MAX_LENGTH, oFile);

    fclose(iFile);
    fclose(oFile);  

    return EXIT_SUCCESS;
}

所以我的问题是打印出数组并在“\n”处剪切每一行的最佳解决方案是什么? (或者创建一个具有动态长度/大小的数组)。

我想过创建一个 int countRows 并在 fileend 变为 true 时从 'zeile' 获取数字,但我如何获取 countColoumns?

主要目标是以 90 度的步长旋转 ASCII 图像,但我被困在输出端。所以我必须使用二维数组,这样我就可以轻松地交换字符。 感谢您的帮助。

【问题讨论】:

  • 为什么不在嵌套循环中 fputc 并在每次通过内部循环的末尾加上 \n
  • 为什么不使用 fgets 逐行阅读?
  • 主要目标是以 90 度的步长旋转 ASCII 图像,但我被困在输出中。所以我必须使用二维数组,这样我就可以轻松地交换字符。

标签: c arrays file multidimensional-array


【解决方案1】:

我,

您可以尝试制作一个这样的函数原型:

char **myFileToArray(char *contentOfFile);

此函数的目的是创建一个数组,该数组将包含图片的每一行。 在此函数中,您计算​​行数(= '/n' 的数量),然后创建一个具有此大小的动态数组。对于数组的每个维度,您动态分配行的长度加上 '/0' 的长度。您将线条复制到维度中,并将“/0”放在维度的每一端。 在此之后你可以返回你的数组。

例如,如果您的文件是:

1.      /\_/\
2.    =( °w° )=
3.      )   (  //
4.     (__ __)//

您将拥有一个大小为 5 的数组,如下所示:

array[0] = "  /\_/\"
array[1] = "=( °w° )="
array[2] = "  )   (  //"
array[3] = " (__ __)//"
array[4] = "/0"

对于打印,您可以创建另一个函数来写入数组并将每个“/0”替换为“/n”。

这个解决方案有点复杂,但我认为它仍然是一个干净的解决方案。

我希望我的解释是明确的对不起我的英语不好,我试图提高!

【讨论】:

  • 它必须是二维数组,因为我想在下一步中旋转 Ascii 图片。
  • 哦..在这种情况下,我们可以使用最长的线,如每个维度的大小,并应用旋转矩阵来切换图像。
【解决方案2】:

要将数组数据写入带有fwrite 的二进制文件,您需要知道要写入的字符数。您只关心使用的字符数(或在您的情况下使用的行数),而不是数组的未初始化/空部分。您可能还希望将每个数组元素的行数和大小作为前两个值写入文件,这样您就会知道要读回多少 x 大小的数组。 (处理字符串,如果您选择,您也可以将空终止字符写入文件)如果您将numlines 的行数设置为unsigned int,那么对于char 类型,如下所示的简单操作@987654325 @:

unsigned maxl = MAX_LENGTH;
fwrite (&numlines, sizeof numlines, 1, oFile);
fwrite (&maxl, sizeof maxl, 1, oFile);
fwrite (elements, MAX_LENGTH, numlines, oFile);

然后要读回它,您读取前 2 个无符号 int 值,这些值是要从文件中读回的数组(或行)大小的数字。

如果元素包含char 以外的其他内容,其中sizeof type &gt; 1,那么您可以将maxlelementsfwrite 更改为(int 示例):

unsigned maxl = MAX_LENGTH * sizeof (int);
...
fwrite (&maxl, sizeof maxl, 1, oFile);
fwrite (elements, MAX_LENGTH * sizeof (int), numlines, oFile);

或者最后一行通常被视为:

fwrite (elements, maxl, numlines, oFile);

目标是以您可以轻松读回的方式写入文件(或记录)。知道元素的数量和大小并将它们保存为写入文件的前两个数字允许您查询保存值所需的大小/类型的文件,然后将它们读回您的程序并验证您的读取。

无需太多额外的努力,您也可以写出一个锯齿状数组,只需在输出中的每一行之前包含要读取的字符(或字节)数。这将允许您将许多大小不均匀的元素组写入文件,从而在此过程中节省一些文件大小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-06
    • 2010-09-26
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 2014-08-25
    • 1970-01-01
    • 2012-12-14
    相关资源
    最近更新 更多