试图一次读取一个字符矩阵

时间:2018-03-04 18:53:12

标签: c++ codeblocks

我正在尝试读取以下输入并将输入矩阵分配给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。

2 个答案:

答案 0 :(得分:3)

替换

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

in >> s[i][j];

说明:

让我们通过打印确切读取的内容来看看发生了什么,但作为数字我们可以与ASCII表进行比较:

#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我们发现getan 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

答案 1 :(得分:0)

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

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时它不会停止读取。而ifstream extraction operator >>对象丢弃它。