Combining a negative sign with a characater in a string array? (C++)

Hi all,

I'm currently working on a project that requires me to read letters from a matrix and use the number that they correspond to to determine the probability of a mutation occurring. I think I have been able to accomplish that for the most part, but when it comes to reading a negative number, it would usually print out just the negative sign, rather than the whole number plus the sign. I'm not allowed to use 2D arrays for this particular project, so what I did was insert the top line of the matrix (called the header) and the rest of the matrix goes into another string. How would I make the string count the negative sign as part of the number? Would putting the matrix into a single-dimension array work instead? Or would I have to do something to make sure the negative sign is attached to the number? Thanks in advance!

Here is what I have for that section so far:

1
2
3
4
5
6
7
8
9
10
11
12
string matrixA;

            for (int i = 0; i < matrixA.length(); i++) {
                if (matrixA[i] == '-') {
                    matrixA[i] = '-' + matrixA[i+1];
                }
                else {
                    matrixA[i] = matrixA[i];
                }
                cout << matrixA[i];
            }
Last edited on
.
.
It isn't entirely clear what the program is trying to achieve. Is it supposed to be converting a string into an integer? Could you provide some samples of the typical input data and the corresponding desired output data.
Dear Chervil,

No problem. I'm supposed to read data from to files and use this matrix (.csv - comma separated file) to determine the number value/coordinate. I have removed the commas from both the code below and from my program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
_	A	R	N	D	C	Q	E	G	H	I	L	K
A	2	-2	0	0	-2	0	0	1	-1	-1	-2	-1
R	-2	6	0	-1	-4	1	-1	-3	2	-2	-3	3
N	0	0	2	2	-4	1	1	0	2	-2	-3	1
D	0	-1	2	4	-5	2	3	1	1	-2	-4	0
C	-2	-4	-4	-5	12	-5	-5	-3	-3	-2	-6	-5
Q	0	1	1	2	-5	4	2	-1	3	-2	-2	1
E	0	-1	1	3	-5	2	4	0	1	-2	-3	0
G	1	-3	0	1	-3	-1	0	5	-2	-3	-4	-2
H	-1	2	2	1	-3	3	1	-2	6	-2	-2	0
I	-1	-2	-2	-2	-2	-2	-2	-3	-2	5	2	-2
L	-2	-3	-3	-4	-6	-2	-3	-4	-2	2	6	-3
K	-1	3	1	0	-5	1	0	-2	0	-2	-3	5
M	-1	0	-2	-3	-5	-1	-2	-3	-2	2	4	0
F	-3	-4	-3	-6	-4	-5	-5	-5	-2	1	2	-5
P	1	0	0	-1	-3	0	-1	0	0	-2	-3	-1
S	1	0	1	0	0	-1	0	1	-1	-1	-3	0
T	1	-1	0	0	-2	-1	0	0	-1	0	-2	0
W	-6	2	-4	-7	-8	-5	-7	-7	-3	-5	-2	-3
Y	-3	-4	-2	-4	0	-4	-4	-5	0	-1	-1	-4
V	0	-2	-2	-2	-2	-2	-2	-1	-2	4	2	-2


I put each line of the matrix into a string (inefficient, I know, but we aren't allowed to use 2D arrays) and use the string array index of the header (top line)
to find the number that corresponds with the other letter's string.

So, if my files look like this:

File A:
ARN

File B:
AAA

The output for the first letter of file A and file B should be 2.
(A, A)
=2

Then for (R, A) the output should be -2.
However, the string that -2 is included in, which is string A (second line of matrix): A2-200-2001 -1-1-2-1, counts the negative sign as a separate value in the string. Meaning that in order to get -2, I would have to manually output both the string array at index '-' and at '2'.

I want to be able to change the string array in a way that will make -2 be in the same index and not one after the other.

Basically I would like the program to do this:
1
2
Index:   0  1  2  3
StringA: A  2 -2  0


Rather than this:
1
2
Index:   0  1  2  3
StringA: A  2  -  2 

I hope that clears up any confusion!
Last edited on
Thanks for the reply. It's getting a bit late here where I live, time for some sleep, so I may not respond very quickly - though of course anyone else is welcome to contribute.
Thanks for the response, Chervil. Have a good night!
There are problems with this code:
1
2
3
4
5
6
7
8
9
10
11
    string matrixA;

    for (int i = 0; i < matrixA.length(); i++) {
        if (matrixA[i] == '-') {
            matrixA[i] = '-' + matrixA[i+1];
        }
        else {
            matrixA[i] = matrixA[i];
        }
        cout << matrixA[i];
    }

matrixA[i] represents a single character in the string, it doesn't really make sense to try to add characters together and then store the result back into the same location. What I think you really need for this in my opinion is an array of integers, where the '-' and the digit can be properly combined into a single number.

How to do this - well in my attempt at this, I used getline() to read each line from the file into a string, then used a stringstream to break it down into individual numeric values.

I noted the comment, "I'm not allowed to use 2D arrays for this particular project" with some cautiousness, because almost anything which I suggest might also be covered by a similar "not allowed for this project" or perhaps "we didn't learn about that yet", so I have to tread cautiously here. For example perhaps stringstream is forbidden. In that case you might use substrings instead, perhaps.

Anyway, my idea is to turn the 2D array into a 1D array. I would use a struct something like this:
1
2
3
4
5
struct decode {
    char first;
    char second;
    int value;
};

That's just a convenient way of grouping together the pair of letters and corresponding numeric value. Then you would end up with array of 240 'decode' elements. If you didn't learn to use struct or class yet, you could use three separate arrays.

The contents would look something like this:
A A 2
A R -2
A N 0
A D 0
A C -2
A Q 0
A E 0
A G 1
A H -1
A I -1
A L -2
A K -1
R A -2
R R 6
R N 0
... etc
... etc.
Y I -1
Y L -1
Y K -4
V A 0
V R -2
V N -2
V D -2
V C -2
V Q -2
V E -2
V G -1
V H -2
V I 4
V L 2
V K -2


Then the program breaks down into two main sections, first building the above array from the 2D matrix file.

The second part is easier, just doing a sequential search for a matching row given the pair of letters. I'd make that into a separate function.

I realise this doesn't fully answer your original question regarding the strings and minus signs and so on, but I was more interested in the taking a high-level view of a possible way of approaching this project.
Last edited on
Hi Chervil,

Thanks for the reply! We haven't thoroughly cover sstream, but would it be better to use stringstream with the code I've come up with so far?

1
2
3
4
5
6
7
            getline(matrixFile, header,'\n'); //gets first line of matrix
            header = eraseComma(header);// my erase comma function
            cout << header << endl;
        
            getline(matrixFile, matrixA, '\n'); //gets second line of matrix
            matrix = eraseComma(matrixA);


-matrixFile is the file I have to read from
-header is the first line of the matrix (the line with no numbers)
-matrixA second line of the matrix (begins with A, 2, -2 etc.)

I then tried doing this matrixStr << matrixA; (matrixStr is variable of stringstream) but when outputting matrixStr.str(), it would still print out the original string with the negative signs detached. How would I actually go about attaching the negative signs using stringstream?

This would however, require to make a separate string for each line of the matrix. I have been trying to do it this way and it works for the most part, but is inefficient. However, most of the code I have written so far incorporates using 21 different strings.

But I also liked your idea about making three arrays/using a class. I did learn about classes, but I'm not exactly sure how I would create a function to an array of decode elements.

If I use three arrays, can the first array which will contain the repeating letter (in this case, A) be created by making a for loop run 21 times (the length of each line in the matrix) with each run inputting an 'A' into the array? (And then do this again for each letter)

And the second array with the top line of the matrix can be created by making two for loops, the outer loop running for as long as the length of the first array and the inner loop running for as long as the top line of the matrix.

The third array is where I am stuck. Would I create a for loop that starts at an index of [1] rather than [0], or am I totally going about this the wrong way?

I apologize in advance if this post is confusing.
Last edited on
.
.
.
.
closed account (j3Rz8vqX)
Not sure what your doing entirely since, but from your original post, it seems as though you would like to print out the negative character with its following integer_character and not use it for calculations.

A character type variable can only hold one character value, hence "-5" or '-' + '5' won't work.


it simple means to printing it out would be to parse(check) if its a usable character and or negative character.

ASCII character codes:
http://www.asciitable.com/

Your only usable characters should be 45(-) and 48 through 57.
45 = '-'
48 = '0'
49 = '1'
50 = '2'
51 = '3'
52 = '4'
53 = '5'
54 = '6'
55 = '7'
56 = '8'
57 = '9'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <string>
using namespace std;
int main()
{
    string matrixA; //Assuming a Huge string

    for (int i = 0; i < matrixA.length(); i++) {
        if (matrixA[i] == '-') {
            cout << matrixA[i] << matrixA[i+1];//only works if your values are single digit
            //print out a space if you need it, for legibility purposes;
            i++; //Skip the next character;
        }
        else{
            if(matrixA[i]>=48 && matrixA[i]<=57){
                cout << matrixA[i];
                //print out a space if you need it, for legibility purposes;
            }
        }
    }
}

I'm assuming you've got bigger fish to tackle after this, good luck.
Hi Dput,

Thanks a lot for your response! I've been trying to figure this out all week. I am currently trying to implement the code you left me in your post. I think I know where to take it from there.

But I was just curious (this is for anyone to jump into) -- since I am reading from a .csv file and all the values are separated by commas, would I be able to get a value (negative or positive number) between the commas and store it as one single index in an array/string?

For example, if the file I'm reading includes 1, -2, 3, -4, is there a way to read in the -2 as one character and store it into a single index of an array/string? I tried using this getline(file, string, ',') in a loop and it would print out a string with no commas, which was great, but the negative signs were detached. Then I tried the following code:
1
2
3
4
5
while (getline(matrixFile, matrixA, ',')) {
        istringstream string(matrix.substr());
        int num;
        string >> num;
    }

I found it somewhere (don't exactly remember where) but when I would cout the int num or the string matrix, it would include the negative sign with the number, which was great, but when I try to assign that number into an index of a string, it would return an empty string. I also don't know much about sstream so I don't really know how to manipulate this code to make it work.
closed account (j3Rz8vqX)
Yes, but you'd have a 2d array.

Literally, an array of strings.

array[0] = "this string";
array[1] = "another string";
...
...
...
array[100] = "possibly last string";

use vectors if your not confident with new/malloc.

As for the comma, you can simply parse it out.

Acquire your complete string from your text file. Check every character in the string using a loop and replace any non-valid characters found with a white space or something( '\0' is the c_string terminator - see below).

Valid characters should be: -,1,2,3,4,5,6,7,8,9,0;
------------------
-2 cannot simply be put as one character.
It can be a signed int, string, or possibly an object , but not a character.
------------------
Either use a 2d array of strings
OR
Use a space as a delimiter and maintain your single string.
//A delimiter is use to determine when something ends.
------------------
There are many ways to design/implement your objective here.
It just depends on how you want to code your way through it and what your allowed to use.
Last edited on
Hi Dput,

Thanks for your response again! I think I've figured out a way to do this. But it involves deleting some characters from a string array. Basically, I would search the string for a negative sign '-' and then delete the character that comes after it. Since I only need to know if the number is negative, just searching for a negative sign later will do. So I guess my question is, will I need a pointer to do this? I've learned a little about pointers but I'm not actually sure how to use it in this case. I'm trying to do this in a function.

1
2
3
4
5
6
7
8
9
10
string fixNegative(string matrix) {
    //searchs through the string line
    for (int i =0; i < matrix.length(); i++) {
        //if it finds a negative sign
        if (matrix[i] == '-') {
            //delete the character that comes after it
            matrix[i+1] = '';//??
        }
    }
}


Once again, thanks a lot. You've been very helpful.
closed account (j3Rz8vqX)
1
2
3
char * s;//c_string; aka pointer to characters (force malloc handling)

string s;//cpp_invoked string; aka managed non-primitive pointer to characters, followed by '\0' (maintains its own length, size, index, etc) 


You should consider programming cpp style if using cpp, rather than c style; nothing wrong with c, it is just you're using cpp.

Maybe consider making a parallel string then copying important values from the original string, strA, to the new string strB.

strA to me sounds like the original buffered string from file, and not important. You could just edit it, but it'd probably be easier to just take what you want out to another string.

---

As for what you were asking..
If you want to index when a value was negative, you could possibly do it this way...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    int d=0; //temporary index for new_matrix
    string new_matrix;
    //searchs through the string line
    for (int i =0; i < matrix.length(); i++) {
        //if it finds a negative sign
        if (matrix[i] == '-') {
            //Edited:
            //store the negative value;
            new_matrix=new_matrix.c_str() + matrix[i];
        }
        else
        {
            if(matrix[i] >= '0' && matrix[i]<='9')
            {
                //Edited:
                //store a blank; indicating positive number;
                new_matrix=new_matrix.c_str() + ' ';
            }
        }
    }


Then when you output, if the new_matrix has a blank, then the value of that index is positive, it its '-', then the value of that index is negative.

ie...

(value_string):first index: '2'
(sign_string):first index: ' '

(value_string):second index: '2'
(sign_string):second index: '-'

(value_string):third index: '0'
(sign_string):third index: ' '

...

and so on...

Edited:
Writing code off the top of my head, something may not work.
Last edited on
Hi Dput,

Thank you for your response. I was able to figure it out thanks to what you wrote in your last couple of posts. I basically just deleted the number after the negative sign and then transferred everything into a brand new string.

Once again, thanks a lot! You've been extremely helpful. Take care!
Topic archived. No new replies allowed.