尝试一次读取一个字符的字符矩阵

Trying to read a matrix of character one character at a time

我正在尝试读取以下输入并将矩阵从输入分配给 char 矩阵。问题是,当我输出矩阵时,它以一种奇怪的方式输出字符。我做错了什么?

输入:

10 10
PPPPPPPPPP
PXXXXTPXXP
PXPPPPXXXP
PXXXPJPPXP
PPPXPXXXXP
CXXXXXPXPP
PXPXXXPXXP
PXPPPPPXXP
PXXXXXXXXP
PPPPPPPPPP

我的代码:

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    ifstream in("tom.in");
    ofstream out("tom.out");
    int n, m;
    char s[101][101];
    in>>n>>m; //read the size of the matrix
    for(int i = 1; i<=n; i++)
        for(int j = 1; j<=m; j++)
            in.get(s[i][j]); //assign each element from the file to the matrix

    for(int i = 1; i<=n; i++)
    {
        out<<endl;
        for(int j = 1; j<=m; j++)
            out<<s[i][j];
    }

    return 0;
}

输出:

PPPPPPPPP
P
PXXXXTPX
XP
PXPPPPX
XXP
PXXXPJ
PPXP
PPPXP
XXXXP
CXXX
XXPXPP
PXP
XXXPXXP
PX
PPPPPXXP
P
XXXXXXXXP

我用的IDE是Codeblocks

替换

in.get(s[i][j]); 

in >> s[i][j];

解释:

让我们通过打印出所读取的内容来了解​​发生了什么,但作为数字,我们可以将其与 ASCII table:

进行比较
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    ifstream in("tom.in");
    ofstream out("tom.out");
    int n, m;
    char x;
    in>>n>>m; //read the size of the matrix
    for(int i = 1; i<=n; i++)
    {
        for(int j = 1; j<=m; j++)
        {
            in.get(x);
            cout << (int)x <<  ' ';
        }
        cout << '\n';
    }
    return 0;
}

这导致

10 80 80 80 80 80 80 80 80 80 
80 10 80 88 88 88 88 84 80 88 
88 80 10 80 88 80 80 80 80 88 
88 88 80 10 80 88 88 88 80 74 
80 80 88 80 10 80 80 80 88 80 
88 88 88 88 80 10 67 88 88 88 
88 88 80 88 80 80 10 80 88 80 
88 88 88 80 88 88 80 10 80 88 
80 80 80 80 80 88 88 80 10 80 
88 88 88 88 88 88 88 88 80 10 

马上我们有一个 10。它不映射到 P、T、J 或 X 等拉丁字符。它是一个“\n”。一个换行符。

检查the documentation for std::istream::get we find get is an unformatted input function。它不会像您习惯的那样为您去除空格。

我们可以添加一些代码来去除行尾,但何必呢?格式化输入函数将为我们做到这一点。

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    ifstream in("tom.in");
    ofstream out("tom.out");
    int n, m;
    char x;
    in>>n>>m; //read the size of the matrix
    for(int i = 1; i<=n; i++)
    {
        for(int j = 1; j<=m; j++)
        {
            in >> x; //  MADE CHANGE HERE
            cout << (int)x <<  ' ';
        }
        cout << '\n';
    }
    return 0;
}

现在输出看起来像

80 80 80 80 80 80 80 80 80 80 
80 88 88 88 88 84 80 88 88 80 
80 88 80 80 80 80 88 88 88 80 
80 88 88 88 80 74 80 80 88 80 
80 80 80 88 80 88 88 88 88 80 
67 88 88 88 88 88 80 88 80 80 
80 88 80 88 88 88 80 88 88 80 
80 88 80 80 80 80 80 88 88 80 
80 88 88 88 88 88 88 88 88 80 
80 80 80 80 80 80 80 80 80 80 

当转换回 ASCII 字符时,这是预期的

PPPPPPPPPP
PXXXXTPXXP
PXPPPPXXXP
PXXXPJPPXP
PPPXPXXXXP
CXXXXXPXPP
PXPXXXPXXP
PXPPPPPXXP
PXXXXXXXXP
PPPPPPPPPP

您可以先读取 multi-dimensional 数组的长度,然后遍历填充数组的所有内容。

std::ifstream in("data.txt");
std::ofstream out("tom.txt");

int n, m;
// verify the lengths
in >> m >> n;
std::cout << n << ", " << m << std::endl;


char** data = new char*[n];
for(auto i(0); i != n; ++i)
    data[i] = new char[m];

for(auto i(0); i != n; ++i)
    for(auto j(0); j != m; ++j)
        in >> data[i][j];

for(auto i(0); i != n; ++i){
    for(auto j(0); j != m; ++j)
        std::cout << data[i][j]; // just to print to the screen. you can write to the second file with `out` object.
    std::cout << std::endl;
}

// clean

for(auto i(0); i != n; ++i)
    delete[]data[i];
delete[]data;

// close streams
in.close();
out.close(); 

正如您在上面看到的,我首先读取了 nm,它们是数组的长度 这意味着输入指针向前移动,这意味着下一次读取将从下一行读取长度。

  • 您的代码中的问题是:in.get() 一次读取一个字符,但在到达 endline character 时不会停止读取。而带有 extraction operator >>ifstream 对象将其丢弃。