从c中读取文件(基本上是某种字符的网格映射)时,最好的方法是什么,并将其放入某种二维数组中,哪个字符可以通过它的坐标访问? / p>
示例输入文件类似于:
ffflli
ffsdfg
fl979p
kl8dfj
并且每个角色可以通过坐标访问,具体取决于它们的位置。即(0,3)左下角坐标
答案 0 :(得分:1)
我建议你采取一种方法
while not end of file
if character pointed by file pointer is not '\n' or EOF
push chracter into array
答案 1 :(得分:1)
您可以执行以下操作:
FILE *f;
f = fopen("sample.txt","r");
char ch, strr[100], *str;
int row = 0, column = 0, i = 0, j = 0;
while(fgets(strr, sizeof strr, f)) {
row++;
if(column < strlen(strr) )
column = strlen(strr);
}
rewind(f);
char arr[row][column];
while(i < row) {
ch = fgetc(f);
while( ch != EOF || ch != '\n') {
arr[i][j] = ch;
j++;
}
i++;
}
fclose(f);
如果文件大小非常大,您还可以避免首次遍历文件。它是通过不必要地将大尺寸分配给数组来避免浪费内存。
答案 2 :(得分:0)
这对我很有用。它遍历一个像提供的那样的infile,填充提供的2D数组,并且空终止未使用的槽。
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <memory.h>
int main(int argc, char* argv[])
{
FILE* infile;
char* file_path = "C:\\Your\\File\\Path\\Here.txt";
char grid[10][10];
unsigned int num_rows = 10;
// Open infile for reading.
if (0 == fopen_s(&infile, file_path, "r"))
{
char character;
unsigned int row = 0;
unsigned int column = 0;
// Iterate through entire infile.
while (!feof(infile))
{
// Scan in next character.
fscanf_s(infile, "%c", &character, 1);
// Check for newline, moving to next grid row when necessary.
if (character == '\n')
{
// Null-terminate/zero rest of row.
grid[row][column] = '\0';
// Move to beginning of next row.
++row;
column = 0;
continue;
}
// Set appropriate cell to next character.
grid[row][column] = character;
++column;
}
// Null-terminate to sever junk in unused slots.
for (; row < num_rows; ++row)
{
grid[row][column] = '\0';
column = 0;
}
// Close file.
fclose(infile);
}
return 0;
}
一些警告:
我假设10x10网格就足够了。如果这对您不起作用,请务必更改尺寸。算法应调整好(对于合理的维度值)。
连续多个换行符可能会导致完全空行。如果您想以不同方式处理此问题,请在阅读输入时检查此案例。
我认为空终止行是理想的行为。如果我错了,请随意做。
我在Visual Studio中编写了这个,用MSVC编译,因此使用了fopen_s()
和fscanf_s()
。如果这是不合需要的,分别对fopen()
和fscanf()
的更改应该相对简单(主要是更改几个语句和函数参数)。
我希望这会对你有所帮助。如果您有任何问题,请告诉我。
答案 3 :(得分:0)
在C中,您可以通过将指针强制转换为正确的类型来访问存储在1D缓冲区(如文件)中的任何2D数组。像这样:
int buffer1D[20] = {
0, 1, 2, 3, 4,
1, 2, 3, 4, 5,
2, 3, 4, 5, 6,
3, 4, 5, 6, 7
};
int* bufferPtr = buffer1D;
int (*twoDPtr)[5]; //a pointer of the correct type
twoDPtr = (int (*)[5])bufferPtr; //the interesting part: the cast
现在您可以将缓冲区作为2D数组访问:
assert(twoDPtr[2][3] == 5);
诀窍是,twoDPtr
是指向2D数据的行数组的指针。因此,当您使用twoDPtr[2]
对其执行指针运算时,它将跳过2D数据的前两行。