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

Time:03-02

My problems here is to take all the integers in a file, and store to an int array (of course without |), and then do something with it (here I just need help to print out the array).

The data from the file is said to be a 10x10 matrix.

My code output is another 10x10 with trash values, as I tried using std::stringstream.

Input:

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

Code:

#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; 
}

The output should be:

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   

My output:

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 

CodePudding user response:

Two issues: You try to read 10x20 when there is only 10x10 in the file. Further your code assumes that there is a | between all adjacent numbers, but thats not the case. There is no | between the last number in a line and the first in the next line.

Change the size accordingly and read full lines before you split them at |:

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

This is minimum changes on your code. Next I would suggest to extract integers from the stream directly instead of first extracting string and then convert them to integers (by placing the strings into another stream and then extracting the integer, you could do this already with the ifstream).

CodePudding user response:

The basic problem is that the content of your input file doesn't map well to the operation that you're trying to do on that content. In particular, you've assumed that every character in your input file is separated by a | character which is not the case since there is a newline between the last character in any particular line and the first character in the next line.

Also, do note that you have created a 2D array that has 10 rows and 20 columns but your input file has only 10 rows and 10 columns.

Better would be to use a 2D std::vector as shown below:


#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;
}

The output of the above program can be seen here.

The advantage of using std::vector over built in array is that :

  1. You don't have to know the how many rows and columns are there in the input.txt file beforehand.
  2. It is not necessary that all rows have the same number of columns.

That is, using std::vector is flexible.

  • Related