簡體   English   中英

從文本文件中讀取矩陣,C ++

[英]Reading of matrix from text file, C++

朋友們! 編程語言是C ++。 我有一個字節矩陣

unsigned char Map[Height][Width];

我用零初始化。 然后我從文本文件中讀取字節矩陣。 當然,文本文件可以比我的矩陣大。 在這種情況下,我必須以這種方式從文件中讀取信息: 在此處輸入圖片說明

文本文件包含其他信息。 我不需要 在另一種情況下,Matrix可以大於文本文件中的信息:

在此處輸入圖片說明

在這種情況下,程序必須從文件讀取所有信息。 未從文件中獲取信息的矩陣部分已被初始化。 沒關系。

在我的情況下,從文件讀取信息到矩陣的最佳方法是什么? 我嘗試使用fgets ,但是它以連續的方式從文件讀取所有信息-逐字節讀取。 但是我不需要讀取額外的字節。 當然,我可以逐字節讀取文件並檢查計數器。 但是我確信這不是最好的解決方案。 是否存在更好的解決方案?

我的文本文件的格式與此處無關。 我從字節字段之類的文件中讀取信息。

將整個文件讀入緩沖區:

FILE *fp;
long len;
char *buf;
fp=fopen("thefileyouwanttoread.txt","rb");
fseek(fp,0,SEEK_END); //go to end
len=ftell(fp); //get position at end (length)
fseek(fp,0,SEEK_SET); //go to beg.
buf=(char *)malloc(len); //malloc buffer
fread(buf,len,1,fp); //read into buffer
fclose(fp);

將文件復制到您的字節數組中,檢查更大的文件以確定如何復制:

char *startByteArr;
unsigned char Map[Height][Width];

startByteArr = &Map[0][0];
if (len > Height*Width){
    memcpy(startByteArr,buf,Height*Width);
else {
    memcpy(startByteArr,buf,len);
}

假設第一個維度相同。 要考慮文件中寬度的變化,可以將memcpy更改為:

char *startByteArr;
char *EndLineFile;
int lineLengthFile;

EndLineFile = strstr (buf,"\r\n");
lineLenghtFile = (int)(EndLineFile-buf);

unsigned char Map[Height][Width];

startByteArr = &Map[0][0];

int i;

if (lineLengthFile > Width){
    for(i = 0; i < Height;i++){
        memcpy(startByteArr+i*Width,buf+i*lineLengthFile,Width);
    }
else {
    for(i = 0; i < Height;i++){
    memcpy(startByteArr+i*Width,buf+i*lineLengthFile,lineLengthFile);
    }
}

我相信這將是最快的方法,只需一次讀取就將整個文件讀入內存,然后將所需的段存儲到字節數組即可。

如果您可以使用fgets()讀取所有行,則可以將第i個字符逐個字符復制到表的第i行。 當遇到行尾或復制了寬度字符時,請停止。 請注意,fgets()可能會在您要刪除的行的末尾留下NL字符(在Windows上為NL + CR)。

重復上述過程,直到您已閱讀“高度”行或到達文件末尾。

我的解決方案基本上是C(因為您說您不熟悉C ++函數)。 如果要使用真正的C ++實現,則應使用標准的C ++庫(fstream,字符串)。

#include <cstdio>
#include <cstring>

#define Height (...)
#define Width  (...)

// I assume that each input line in the file can contain at most width * 3 characters.
// Three extra characters for NL, CR, 0.
// Change this if you expect the file to contain longer lines.
#define BUFFER_WIDTH (Width * 3 + 3)

unsigned char Map[Height][Width];

unsigned char line[BUFFER_WIDTH];

// Remove CR, NL at the end of the line.
void clean_line(char *line)
{
    int len = strlen(line);

    while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r'))
    {
        line[len - 1] = '\0';
        len--;
    }
}

void read_table(const char *filename)
{
    FILE *fp = fopen(filename, "r");

    int row = 0;
    while (!feof(fp) && row < Height)
    {
        fgets(line, BUFFER_WIDTH, fp);
        clean_line(line);

        int len = strlen(line);
        int rowLen = len > Width ? Width : len;
        for (int col = 0; col < rowLen; col++)
        {
            Map[row][col] = line[col];
        }

        row++;
    }

    fclose(fp);
}

假設您的文本文件如下所示:

3254352
6536543
8875687
4315254
5345435
1212122

標准庫流的解決方案是這樣的:

#include <fstream>
#include <string>

int main()
{
    std::ifstream matrix_file("matrix.txt");

    const size_t Width = 5;
    const size_t Height = 5;
    unsigned char Map[Width][Height];

    size_t line_count = 0;
    std::string line;

    while (std::getline(matrix_file, line) && line_count < Height) {
        line.resize(Width);
        for (size_t i = 0; i < line.length(); ++i)
            Map[i][line_count] = line[i];
        ++line_count;
    }
    if (line_count < Height) {
         // the file didn't have enough lines to fill our matrix,
         // so we'll need to fill the rest with zeroes here
    }
}

line.resize(Width); 當Width大於文件中該行的長度時,以上一行將自動在字符串中放置空字符。 另外,在嘗試讀取流之前,請不要忘記檢查流是否已成功打開fstream::is_open()例如fstream::is_open() )。 為了簡潔起見,我跳過了這張支票。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM