将具有特殊字符的字符串数组转换为 int 数组。输入来自文件

Convert a string array with special characters to an int array. Inputs are from a file

我这里的问题是把一个文件中的所有整数,存储到一个int数组(当然没有|),然后用它做一些事情(这里我只需要帮助打印出来数组)。

据说文件中的数据是一个 10x10 矩阵。

我的代码输出是另一个带有垃圾值的 10x10,因为我尝试使用 std::stringstream

输入:

1|11|2|13|2|2|2|11|13|2
1|11|2|13|2|2|2|13|2|11
1|13|1|13|2|2|2|2|2|2
1|13|1|12|2|2|2|2|2|2
1|13|1|13|1|2|2|2|2|2
1|13|1|13|1|1|2|2|2|2
1|13|1|13|1|1|1|2|2|2
1|13|1|13|1|1|1|1|2|2
1|13|1|13|1|1|1|1|1|2 
1|13|1|13|1|1|1|1|1|1

代码:

#include<iostream>
#include<cstring>
#include<fstream>
#include<sstream>
using namespace std;

int main(){
    //read data from file and store in a 2d array
    ifstream myfile("input.txt");
    string arr[10][20];
    for(int i=0;i<10;i++){
        for(int j=0;j<20;j++){
            getline(myfile,arr[i][j],'|');
        }
    }
    //convert string to int
    //use stringstream
    int arr2[10][20];
    for(int i=0;i<10;i++){
        for(int j=0;j<20;j++){
            stringstream ss;
            ss<<arr[i][j];
            ss>>arr2[i][j];
        }
    }
    //print arr2
    for(int i=0;i<10;i++){
        for(int j=0;j<20;j++){
            cout<<arr2[i][j]<<" ";
        }
        cout<<endl;
    }
    myfile.close();
    return 0; 
}

输出应该是:

1 11 2 13 2 2 2 11 13 2
1 11 2 13 2 2 2 13 2 11
1 13 1 13 2 2 2 2 2 2
1 13 1 12 2 2 2 2 2 2
1 13 1 13 1 2 2 2 2 2
1 13 1 13 1 1 2 2 2 2
1 13 1 13 1 1 1 2 2 2
1 13 1 13 1 1 1 1 2 2
1 13 1 13 1 1 1 1 1 2 
1 13 1 13 1 1 1 1 1 1   

我的输出:

1 11 2 13 2 2 2 11 13 2 
1 13 2 2 2 2 2 2 13 1 
1 2 2 2 2 2 13 1 13 1 
1 2 2 2 13 1 13 1 1 1 
1 2 13 1 13 1 1 1 1 1 
1994842136 12 7086696 7085352 1994774642 0 1994842144 1994771436 0 0 
6416848 2004213955 7086772 6416972 12 7086696 0 4 48 1994842112 
2004213726 1 7149280 7149288 7086696 0 1988425164 0 2003400672 12 
1999860416 6416972 2 1999966512 1999657456 1999691632 1999846272 1999845632 1999819744 1999860464 
4194304 1994719472 0 6417024 0 6418312 2004471984 775517426 -2 6417120 

两个问题:当文件中只有 10x10 时,您尝试读取 10x20。此外,您的代码假定所有相邻数字之间都有一个 |,但事实并非如此。一行中的最后一个数字和下一行中的第一个数字之间没有|

相应地更改大小并阅读整行,然后在 |:

拆分它们
string arr[10][10];
for(int i=0;i<10;i++){
    std::string line;
    getline(myfile,line);
    std::stringstream linestream{line};
    for(int j=0;j<10;j++){
        getline(linestream,arr[i][j],'|');
    }
}

Live Demo

这是对您的代码所做的最小更改。接下来我建议直接从流中提取整数而不是先提取字符串然后将它们转换为整数(通过将字符串放入另一个流然后提取整数,您已经可以使用 ifstream 执行此操作)。

基本的问题 是输入文件的内容不能很好地映射到您尝试对该内容执行的操作。特别是,您假设输入文件中的每个字符都由 | 字符分隔,但事实并非如此,因为在任何特定行的最后一个字符和下一行的第一个字符之间有一个换行符.

此外,请注意您创建了一个具有 10 行和 20 列的二维数组,但您的输入文件只有 10 行和 10 列.

最好使用 2D std::vector,如下所示:


#include <iostream>
#include<sstream>
#include<string>
#include<vector>
#include <fstream>

int main()
{
    std::ifstream inputFile("input.txt");
    std::string line;
    
    //create a 2D vector 
    std::vector<std::vector<int>> arr;
    
    int num = 0; //this will hold the current integer value from the file 
    std::string numTemp;
    if(inputFile)
    {
        while(std::getline(inputFile, line)) //read line by line 
        {
            std::vector<int> temp;//create a 1D vector 
            std::istringstream ss(line);
            
            while(std::getline(ss, numTemp, '|') && (std::istringstream(numTemp) >> num)) //read integer by integer 
            {
                //emplace_back the current number num to the temp vector 
                temp.emplace_back(num);
            }
            
            //emplace_back the current 1D vector temp to the 2D vector arr
            arr.emplace_back(temp);
        }
    }
    else 
    {
        std::cout<<"input file cannot be opened"<<std::endl;
    }
    //lets confirm if our 2D vector contains all the elements correctly
    for(const auto& row: arr)
    {
        for(const auto& col: row)
        {
            std::cout<<col<<" ";
        }
        std::cout<<std::endl;
    }
    return 0;
}

上面程序的输出可见here.

使用 std::vector 优于内置数组的 优势 是:

  1. 您不必事先知道 input.txt 文件中有多少行和列。
  2. 不必所有行的列数都相同。

也就是说,使用std::vector是灵活的。