1

I have some troubles with parsing matrix file. It looks sth like this:

#  Matrix made by matblas from blosum62.iij 
#  * column uses minimum score 
#  BLOSUM Clustered Scoring Matrix in 1/2 Bit Units 
#  Blocks Database = /data/blocks_5.0/blocks.dat 
#  Cluster Percentage: >= 62 
#  Entropy =  0.6979, Expected =  -0.5209 
  A  R  N  D  C  Q  E  G  H  I  L  K  M  F  P  S  T  W  Y  V  B  Z  X  * 
A  4 -1 -2 -2  0 -1 -1  0 -2 -1 -1 -1 -1 -2 -1  1  0 -3 -2  0 -2 -1  0 -4 
R -1  5  0 -2 -3  1  0 -2  0 -3 -2  2 -1 -3 -2 -1 -1 -3 -2 -3 -1  0 -1 -4 
N -2  0  6  1 -3  0  0  0  1 -3 -3  0 -2 -3 -2  1  0 -4 -2 -3  3  0 -1 -4 
D -2 -2  1  6 -3  0  2 -1 -1 -3 -4 -1 -3 -3 -1  0 -1 -4 -3 -3  4  1 -1 -4 
C  0 -3 -3 -3  9 -3 -4 -3 -3 -1 -1 -3 -1 -2 -3 -1 -1 -2 -2 -1 -3 -3 -2 -4 
Q -1  1  0  0 -3  5  2 -2  0 -3 -2  1  0 -3 -1  0 -1 -2 -1 -2  0  3 -1 -4 
E -1  0  0  2 -4  2  5 -2  0 -3 -3  1 -2 -3 -1  0 -1 -3 -2 -2  1  4 -1 -4 
G  0 -2  0 -1 -3 -2 -2  6 -2 -4 -4 -2 -3 -3 -2  0 -2 -2 -3 -3 -1 -2 -1 -4 
H -2  0  1 -1 -3  0  0 -2  8 -3 -3 -1 -2 -1 -2 -1 -2 -2  2 -3  0  0 -1 -4 
I -1 -3 -3 -3 -1 -3 -3 -4 -3  4  2 -3  1  0 -3 -2 -1 -3 -1  3 -3 -3 -1 -4 
L -1 -2 -3 -4 -1 -2 -3 -4 -3  2  4 -2  2  0 -3 -2 -1 -2 -1  1 -4 -3 -1 -4 
K -1  2  0 -1 -3  1  1 -2 -1 -3 -2  5 -1 -3 -1  0 -1 -3 -2 -2  0  1 -1 -4 
M -1 -1 -2 -3 -1  0 -2 -3 -2  1  2 -1  5  0 -2 -1 -1 -1 -1  1 -3 -1 -1 -4 
F -2 -3 -3 -3 -2 -3 -3 -3 -1  0  0 -3  0  6 -4 -2 -2  1  3 -1 -3 -3 -1 -4 
P -1 -2 -2 -1 -3 -1 -1 -2 -2 -3 -3 -1 -2 -4  7 -1 -1 -4 -3 -2 -2 -1 -2 -4 
S  1 -1  1  0 -1  0  0  0 -1 -2 -2  0 -1 -2 -1  4  1 -3 -2 -2  0  0  0 -4 
T  0 -1  0 -1 -1 -1 -1 -2 -2 -1 -1 -1 -1 -2 -1  1  5 -2 -2  0 -1 -1  0 -4 
W -3 -3 -4 -4 -2 -2 -3 -2 -2 -3 -2 -3 -1  1 -4 -3 -2 11  2 -3 -4 -3 -2 -4 
Y -2 -2 -2 -3 -2 -1 -2 -3  2 -1 -1 -2 -1  3 -3 -2 -2  2  7 -1 -3 -2 -1 -4 
V  0 -3 -3 -3 -1 -2 -2 -3 -3  3  1 -2  1 -1 -2 -2  0 -3 -1  4 -3 -2 -1 -4 
B -2 -1  3  4 -3  0  1 -1  0 -3 -4  0 -3 -3 -2  0 -1 -4 -3 -3  4  1 -1 -4 
Z -1  0  0  1 -3  3  4 -2  0 -3 -3  1 -1 -3 -1  0 -1 -3 -2 -2  1  4 -1 -4 
X  0 -1 -1 -1 -2 -1 -1 -1 -1 -1 -1 -1 -1 -1 -2  0  0 -2 -1 -1 -1 -1 -1 -4 
* -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4  1

It is a part of bigger program, but first I want to check it separately before putting it into a class. So my code looks like this:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

char readfile(char * file)
{
    int lines, cols;
    char matrix[30][30];
    ifstream ifs(file, ios::in);
    ifs.precision(2);
    ifs.setf(ios::fixed, ios::showpoint);
    ifs >> matrix[lines][cols];
    while(!ifs.eof())
    {
        string linijka;
        getline(ifs, linijka);
        if (linijka[0] != '#')
        {
            for (lines = 0; lines < 30; lines++)
            {
                for (cols = 0; cols < 30; cols++)
                {
                    return matrix[lines][cols];
                }
            }
        }
    } 

    ifs.close();
}

int main(int argc, char * argv[1])
{
    cout << "Matrix:\n" << readfile(argv[1]) << endl;
    return 0;
}

Everything is compiled without errors. Unfortuntely matrix is empty. After executing it I receive sth like that:

mateusz@viking:$ ./matpars submat/BLOSUM62.txt 
Matrix:

I need it to get mark from cell e. g. [T][G].

Any ideas? I'll be very thankfully. ;-)

3 Answers 3

3

Your code has a fundamental problem in it: as soon as it reaches that return statement, the function will end, and the rest of your file won't be parsed.

This is why you're not seeing anything; it's printing out the first character in the first line of your file ONLY, and that happens to be the blank space before the first A column marker.

EDIT: Actually, looking closer, it appears there's a more significant problem. You seem to be expecting that first ifs >> matrix line to load the entire file into the array for you, which it cannot do.

You seem to be a beginning programmer. To be honest, I'd recommend you start out with an easier language than C++, such as Python or Ruby.

Sign up to request clarification or add additional context in comments.

7 Comments

so how can I store data in this matrix? I don't need to print it on standard input or sth like that. I need only to store it for searching by program for scores (numbers in matrix file) by columns and lines.
The 'ifs >> matrix' line belongs in the inner loop, where you have that 'return' line now. The '>>' operator there only pulls out one number at a time. Furthermore, you also do not need that getline call; that's storing a whole line of input in the linijka variable, but you aren't using that line at all, just throwing it away.
Finally, once you've filled the matrix, you need to give it back to the caller. The easiest way is to simply return the array with a return matrix; line at the end of your readfile function. You'll also have to change main to accept this matrix back.
I'm beginning programmer indeed. I'm learning python too, it's more newbie-friendly. Unfortunately it is from my classes and I need to do that project in C++. :/ Moreover I do not study computer science so that's why I am not very keen on C++ and programming. :(
Oh, one more thing to watch out for; the row and column headers will trip up C++, since it will attempt to convert them into numbers so that it can store them in your array. You have to skip the row header line, and the first element of each data row.
|
2

There are several problems. As has already been mentionned, you return from the middle of the nested loop: certainly not what you want to do. Also, before the loop, you read into matrix[lines][cols]: this is undefined behavior, since you've never initialized lines and cols. (Typically, you wouldn't even define them until in the for, e.g.: for ( int lines = 0; lines < 30; ++ lines ) for ( int cols = 0; cols < 30; ++ cols ) .) Still, the line is syntactically valid, and reads the first non-blank char from the input (in your case, the initial #). And writes it somewhere, although it's anybody's guess where.

Some additional comments: -- The argument to readfile should be char const*, and not char*. Or even std::string const&.

-- I'm not sure what you're trying to read into the matrix: where do the 30 come from in its definition? And shouldn't it be "int matrix[x][x]", or something along those lines. Or more likely: "std::vector >".

-- You're reading integers (or as written, a single char); precision has no effect. It also has no effect on input.

-- And what is "ifs.setf(ios::fixed, ios::showpoint)" supposed to do. (As it happens, it almost certainly sets the floating point format to its default---and not to fixed---, although I think the behavior is formally undefined.) Not that it matters; these flags also have no effect on input.

-- The "while(!ifs.eof())" is also certainly wrong. The expression ifs.eof() is only reliable after an input operation has failed.

In addition, you'll need some special handling for the first non-comment line, and some special handling for the first character in each line.

-- James Kanze

Comments

1

I get the feeling this is homework, so I don't want to solve it outright for you. :-) However, to help you along, here's a Python implementation written in a C++ish style:

#!/usr/bin/python

import sys

def readfile(fname):
  # A dynamic array; a similar thing in C++ is vector<int>.
  # If you want a two-dimensional dynamic array in C++, it's a vector< vector<int> >
  # It's not as efficient as a fixed-size C-style array, but much more convenient!
  mat = []
  fh = file(fname)

  for line in fh: # Read through the file line by line
    cells = line.split() # This is an array of all the items in this line

    # Skip blank lines, and comment lines that start with the hash symbol
    if len(cells) == 0 or cells[0] == '#':
      continue 

    # Skip lines that end with * (lets us avoid the column titles line)
    if cells[len(cells)-1] == "*":
      continue

    # Add a row to the matrix, in C++ it would be something like mat.push_back(vector<int>())
    mat.append([])

    # Add all the items except the first one as numbers
    for i in range(1, len(cells)): # Equivalent to C++'s "for (int i = 1; i < cells.size; ++i) { }"
      mat[len(mat)-1].append(int(cells[i]))

  fh.close()
  return mat

mat = readfile(sys.argv[1])
print "Cell at 3,4 is %u" % mat[3][4]

2 Comments

Yeah, it is like a homework so I am searching rather for some tip, no for ready solutions. ;) Thanks so much! It is very usefull! ;)
No problem. Let me give one more C++ hint too: I see you're already on the right track using the std::string instead of C-style char* strings. However, you're still using C arrays, which can be really finicky. In the python code above I mention a C++ thing called a 'vector'; this is worth looking up, since it's much easier to work with. This is the hardest part about learning C++: although everything that can be done in C can still be done in C++, it isn't necessarily a good idea anymore! Despite that, lots of "C++" tutorials still teach C-ish techniques.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.