Inputting a relationship array - c++

I am trying to input an binary array which represents a relationship. As an example, the array:
001
000
100
would output (0,2),(2,0)
To do this I'm trying to grab characters one at a time from input, and then change counters based on encountering a newline.
Here is my code so far.
char inChar;
int x = 0;
int y = 0;
while (inChar = ins.get() != '$') {
//$ is used to terminate input
vector <int> orderedPair;
if(inChar == '\n') {
y++;
x=0;
} else {
x++;
}
cout << inChar;
int isPair = inChar - '0';
if(isPair == 1){
orderedPair.push_back(x);
orderedPair.push_back(y);
pointsList.push_back(orderedPair);
orderedPair.clear();
}
}
However, that cout line just outputs... smiley faces? No matter what I enter, I just get smiley faces. I'm lost here. I've looked for any accidentally assignment, and I thought it might be an issue with my typecasting but that is later.

inChar = ins.get() != '$' means inChar = (ins.get() != '$') and whether the character read is equal to '$' or not will be stored to inChar instead of the character itself. You can use (inChar = ins.get()) != '$' to save the input with checking if the input is '$'.
Also note that orderedPair will be cleared on each iteration because it is declared as local variable of the block, so you won't need orderedPair.clear();.

Related

How to find the duplicate

/* I have written a code for a simple hangman based on instructions given, I just want to know how to detect the duplicated inputs. For this code, It only detects correct letters and the length
For example:
user input: HAM
H
A
A
HANGMAN! */
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
// Word to be guessed can be assumed to be at most 20 characters long (including end-of-string null character)
char HangmanWord[20];
// Variable to store current guess
char GuessLetter;
int count = 0;
std::cin >> HangmanWord;
//char guessedletter[strlen(HangmanWord)];
//int j = 0;
bool valid = true;
// Check that input word only consists of uppercase English letters
for (int i = 0; i < strlen(HangmanWord); i++)
{
if ((HangmanWord[i] > 'Z') || (HangmanWord[i] < 'A'))
{
valid = false;
break;
}
}
while (valid == true)
{
std::cin >> GuessLetter; //Takes the Guess letter
if ((GuessLetter > 'Z') || (GuessLetter < 'A')) //Check that guessed letter is uppercase
{
break;
}
else
{
for (int i = 0; i < strlen(HangmanWord); i++) //loop to check every letter in word
{
if (GuessLetter == HangmanWord[i]) { //if the letter is equal to any letter in the word the count increases
count++;
break;
}
if (i == strlen(HangmanWord) - 1) { //If no letter is equal to any letter in the word the program exits
valid = false;
}
}
if (count == strlen(HangmanWord)) { //Checks if all letters were guessed and exits the loop after
valid = false;
}
}
}
if (count == strlen(HangmanWord)) { //Checks if all letters were guessed correct to print Hangman
cout << "HANGMAN!\n";
valid = false;
}
If you want to detect whether a letter has already been input, you can work with ASCII characters being represented by numbers. Assuming we limit ourselves to uppercase letters, 'A' is 65 and 'Z' is 90.
We can do math with these. 'A' - 'A' is 0 and 'C' - 'A' is 2.
We also know that arrays are indexed starting from zero.
We can put these things together to create an array of boolean values, and flag them as letters are guessed.
std::array<std::bool, 26> already_guessed;
std::fill(already_guess.begin(), already_guessed.end(), false);
And we can then check on whether a letter has been guessed by looking it up. Consider, for instance, checking whether 'D' has been guessed. They should start out false, as nothing has been guessed at the beginning.
already_guessed['D' - 'A']
If it hasn't, we can mark it as guessed:
already_guessed['D' - 'A'] = true

How to store in a string and convert to character array?

Write a C++ program to perform addition of two hexadecimal numerals which are less than 100 digits long. Use arrays to store hexadecimal numerals as arrays of characters.the solution is to add the corresponding digits in the format of hexadecimal directly. From right to left, add one to the digit on the left if the sum of the current digits exceed 16. You should be able to handle the case when two numbers have different digits.
The correct way to get the input is to store as character array. You can either first store in a string and convert to character array, or you can use methods such as cin.getline(), getc(), cin.get() to read in the characters.
I don't know what is wrong with my program and it I don't know how to use the function getline() and eof()
char a[number1],b[number1],c[number2],h;
int m,n,p(0),q(0),k,d[number1],z[number1],s[number2],L,M;
cout<<"Input two hexadecimal numerals(both of them within 100 digits):\n";
cin.getline(a,100);
cin.getline(b,100);
int x=strlen(a) ;
int y=strlen(b);
for(int i=0;i<(x/2);i++)
{
m=x-1-i;
h=a[i];
a[i]=a[m];
a[m]=h;
}
for(int j=0;j<(y/2);j++)
{
n=y-1-j;
h=b[j];
b[j]=b[n];
b[n]=h;
}
if(x>y)
{
for(int o=0;o<x;o++)//calculate a add b
{
if(o>=(y-1))
z[o]=0;//let array b(with no character)=0
if(a[o]=='A')
d[o]=10;
else if(a[o]=='B')
d[o]=11;
else if(a[o]=='C')
d[o]=12;
else if(a[o]=='D')
d[o]=13;
else if(a[o]=='E')
d[o]=14;
else if(a[o]=='F')
d[o]=15;
else if(a[o]=='0')
d[o]=0;
else if(a[o]=='1')
d[o]=1;
else if(a[o]=='2')
d[o]=2;
else if(a[o]=='3')
d[o]=3;
else if(a[o]=='4')
d[o]=4;
else if(a[o]=='5')
d[o]=5;
else if(a[o]=='6')
d[o]=6;
else if(a[o]=='7')
d[o]=7;
else if(a[o]=='8')
d[o]=8;
else if(a[o]=='9')
d[o]=9;
if(b[o]=='A')
z[o]=10;
else if(b[o]=='B')
z[o]=11;
else if(b[o]=='C')
z[o]=12;
else if(b[o]=='D')
z[o]=13;
else if(b[o]=='E')
z[o]=14;
else if(b[o]=='F')
z[o]=15;
else if(b[o]=='0')
z[o]=0;
else if(b[o]=='1')
z[o]=1;
else if(b[o]=='2')
z[o]=2;
else if(b[o]=='3')
z[o]=3;
else if(b[o]=='4')
z[o]=4;
else if(b[o]=='5')
z[o]=5;
else if(b[o]=='6')
z[o]=6;
else if(b[o]=='7')
z[o]=7;
else if(b[o]=='8')
z[o]=8;
else if(b[o]=='9')
z[o]=9;
p=d[o]+z[o]+q;
if(p>=16)//p is the remained number
{
q=1;
p=p%16;
}
else
q=0;
if(p==0)
c[o]='0';
else if(p==1)
c[o]='1';
else if(p==2)
c[o]='2';
else if(p==3)
c[o]='3';
else if(p==4)
c[o]='4';
else if(p==5)
c[o]='5';
else if(p==6)
c[o]='6';
else if(p==7)
c[o]='7';
else if(p==8)
c[o]='8';
else if(p==9)
c[o]='9';
else if(p==10)
c[o]='A';
else if(p==11)
c[o]='B';
else if(p==12)
c[o]='C';
else if(p==13)
c[o]='D';
else if(p==14)
c[o]='E';
else if(p==15)
c[o]='F';
}
k=x+1;
if(q==1)//calculate c[k]
{
c[k]='1';
for(int f=0;f<=(k/2);f++)
{
m=k-f;
h=c[f];
c[f]=c[m];
c[m]=h;
}
}
else
{
for(int e=0;e<=(x/2);e++)
{
m=x-e;
h=c[e];
c[e]=c[m];
c[m]=h;
}
}
}
if(x=y)
{
for(int o=0;o<x;o++)//calculate a add b
{
if(a[o]=='A')
d[o]=10;
else if(a[o]=='B')
d[o]=11;
else if(a[o]=='C')
d[o]=12;
else if(a[o]=='D')
d[o]=13;
else if(a[o]=='E')
d[o]=14;
else if(a[o]=='F')
d[o]=15;
else if(a[o]=='0')
d[o]=0;
else if(a[o]=='1')
d[o]=1;
else if(a[o]=='2')
d[o]=2;
else if(a[o]=='3')
d[o]=3;
else if(a[o]=='4')
d[o]=4;
else if(a[o]=='5')
d[o]=5;
else if(a[o]=='6')
d[o]=6;
else if(a[o]=='7')
d[o]=7;
else if(a[o]=='8')
d[o]=8;
else if(a[o]=='9')
d[o]=9;
if(b[o]=='A')
z[o]=10;
else if(b[o]=='B')
z[o]=11;
else if(b[o]=='C')
z[o]=12;
else if(b[o]=='D')
z[o]=13;
else if(b[o]=='E')
z[o]=14;
else if(b[o]=='F')
z[o]=15;
else if(b[o]=='0')
z[o]=0;
else if(b[o]=='1')
z[o]=1;
else if(b[o]=='2')
z[o]=2;
else if(b[o]=='3')
z[o]=3;
else if(b[o]=='4')
z[o]=4;
else if(b[o]=='5')
z[o]=5;
else if(b[o]=='6')
z[o]=6;
else if(b[o]=='7')
z[o]=7;
else if(b[o]=='8')
z[o]=8;
else if(b[o]=='9')
z[o]=9;
p=d[o]+z[o]+q;
M=p;
if(p>=16)
{
q=1;
p=p%16;
}
else
q=0;
s[o]=p;
if(p==0)
c[o]='0';
else if(p==1)
c[o]='1';
else if(p==2)
c[o]='2';
else if(p==3)
c[o]='3';
else if(p==4)
c[o]='4';
else if(p==5)
c[o]='5';
else if(p==6)
c[o]='6';
else if(p==7)
c[o]='7';
else if(p==8)
c[o]='8';
else if(p==9)
c[o]='9';
else if(p==10)
c[o]='A';
else if(p==11)
c[o]='B';
else if(p==12)
c[o]='C';
else if(p==13)
c[o]='D';
else if(p==14)
c[o]='E';
else if(p==15)
c[o]='F';
}
k=x+1;
if(q==1)
{
c[k]='1';
for(int f=0;f<=(k/2);f++)
{
m=k-f;
h=c[f];
c[f]=c[m];
c[m]=h;
}
}
else
{
for(int e=0;e<=(x/2);e++)
{
m=x-e;
h=c[e];
c[e]=c[m];
c[m]=h;
}
}
}
Lets look at what cin.getline does:
Extracts characters from stream until end of line. After constructing
and checking the sentry object, extracts characters from *this and
stores them in successive locations of the array whose first element
is pointed to by s, until any of the following occurs (tested in the
order shown):
end of file condition occurs in the input sequence (in which case setstate(eofbit) is executed)
the next available character c is the delimiter, as determined by Traits::eq(c, delim). The delimiter is extracted (unlike basic_istream::get()) and counted towards gcount(), but is not stored.
count-1 characters have been extracted (in which case setstate(failbit) is executed).
If the function extracts no characters (e.g. if count < 1), setstate(failbit)
is executed. In any case, if count>0, it then stores a null character
CharT() into the next successive location of the array and updates
gcount().
The result of that is in all cases, s now points to a null terminated string, of at most count-1 characters.
In your usage, you have up to 99 digits, and can use strlen to count exactly how many. eof is not a character, nor it is a member function of char.
You then reverse in place the inputs, and go about your overly repetitious conversions.
However, it's much simpler to use functions, both those you write yourself and those provided by the standard.
// translate from '0' - '9', 'A' - 'F', 'a' - 'f' to 0 - 15
static std::map<char, int> hexToDec { { '0', 0 }, { '1', 1 }, ... { 'f', 15 }, { 'F', 15 } };
// translate from 0 - 15 to '0' - '9', 'A' - 'F'
static std::map<int, char> decToHex { { 0, '0' }, { 1, '1' }, ... { 15, 'F' } };
std::pair<char, bool> hex_add(char left, char right, bool carry)
{
// translate each hex "digit" and add them
int sum = hexToDec[left] + hexToDec[right];
// we have a carry from the previous sum
if (carry) { ++sum; }
// translate back to hex, and check if carry
return std::make_pair(decToHex[sum % 16], sum >= 16);
}
int main()
{
std::cout << "Input two hexadecimal numerals(both of them within 100 digits):\n";
// read two strings
std::string first, second;
std::cin >> first >> second;
// reserve enough for final carry
std::string reverse_result(std::max(first.size(), second.size()) + 1, '\0');
// traverse the strings in reverse
std::string::const_reverse_iterator fit = first.rbegin();
std::string::const_reverse_iterator sit = second.rbegin();
std::string::iterator rit = reverse_result.begin();
bool carry = false;
// while there are letters in both inputs, add (with carry) from both
for (; (fit != first.rend()) && (sit != second.rend()); ++fit, ++sit, ++rit)
{
std::tie(*rit, carry) = hex_add(*fit, *sit, carry);
}
// now add the remaining digits of first (will do nothing if second is longer)
for (; (fit != first.rend()); ++fit)
{
// we need to account for a carry in the last place
// potentially all the way up if we are adding e.g. "FFFF" to "1"
std::tie(*rit, carry) = hex_add(*fit, *rit++, carry);
}
// or add the remaining digits of second
for (; (sit != second.rend()); ++sit)
{
// we need to account for a carry in the last place
// potentially all the way up if we are adding e.g. "FFFF" to "1"
std::tie(*rit, carry) = hex_add(*sit, *rit++, carry);
}
// result has been assembled in reverse, so output it reversed
std::cout << reverse_result.reverse();
}
Regarding the text of your problem: “add one to the digit on the left if the sum of the current digits exceed 16” is wrong; it should be 15, not 16.
Regarding your code: I did not have the patience to read all your code, however:
I have noticed one long if/else. Use a switch (but you do not need one).
To find out if a character is a hex digit use isxdigit (#include <cctype>).
The user might input uppercase and lowercase characters: convert them to the same case using toupper/tolower.
To convert a hex digit to an integer:
if the digit is between ‘0’ and ‘9’ simply subtract ‘0’. This works because the codes for ‘0’, ‘1’… are 0x30, 0x31... (google ASCII codes).
if the digit is between ‘A’ and ‘F’, subtract ‘A’ and add 10.
Solving the problem:
“less than 100 digits long” This is a clear indication regarding how your data must be stored: a simple 100 long array, no std::string, no std::vector:
#define MAX_DIGITS 100
typedef int long_hex_t[MAX_DIGITS];
In other words your numbers are 100 digits wide, at most.
Decide how you store the number: least significant digit first or last? I would chose to store the least significant first. 123 is stored as {3,2,1,0,…0}
Use functions to simplify your code. You will need three functions: read, print and add:
int main()
{
long_hex_t a;
read( a );
long_hex_t b;
read( b );
long_hex_t c;
add( c, a, b );
print( c );
return 0;
}
The easiest function to write is add followed by print and read.
For read use get and putback to analyze the input stream: get extracts the next character from stream and putback is inserting it back in stream (if we do not know how to handle it).
Here it is a full solution (try it):
#include <iostream>
#include <cctype>
#define MAX_DIGITS 100
typedef int long_hex_t[MAX_DIGITS];
void add( long_hex_t c, long_hex_t a, long_hex_t b )
{
int carry = 0;
for ( int i = 0; i < MAX_DIGITS; ++i )
{
int t = a[i] + b[i] + carry;
c[i] = t % 16;
carry = t / 16;
}
}
void print( long_hex_t h )
{
//
int i;
// skip leading zeros
for ( i = MAX_DIGITS - 1; i >= 0 && h[i] == 0; --i )
;
// all zero
if ( i < 0 )
{
std::cout << '0';
return;
}
// print remaining digits
for ( i; i >= 0; --i )
std::cout << char( h[i] < 10 ? h[i] + '0' : h[i] - 10 + 'A' );
}
void read( long_hex_t h )
{
// skip ws
std::ws( std::cin );
// skip zeros
{
char c;
while ( std::cin.get( c ) && c == '0' )
;
std::cin.putback( c );
}
//
int count;
{
int i;
for ( i = 0; i < MAX_DIGITS; ++i )
{
char c;
if ( !std::cin.get( c ) )
break;
if ( !std::isxdigit( c ) )
{
std::cin.putback( c );
break;
}
c = std::toupper( c );
h[i] = c <= '9'
? ( c - '0' )
: ( c - 'A' + 10 );
}
count = i;
}
// reverse
for ( int i = 0, ri = count - 1; i < count / 2; ++i, --ri )
{
int t = h[i];
h[i] = h[ri];
h[ri] = t;
}
// fill the rest with zero
for ( int i = count; i < MAX_DIGITS; ++i )
h[i] = 0;
}
int main()
{
long_hex_t a;
read( a );
long_hex_t b;
read( b );
long_hex_t c;
add( c, a, b );
print( c );
return 0;
}
This is a long answer. Because you have much bug in your code. Your using of getline is ok. But your are calling a eof() like e.eof() which is wrong. If you have looked at your compilation error, you would see that it was complaining about calling eof() on the variable e because it is of non-class type. Simple meaning it is not an object of some class. You cannot put the dot operator . on primitive types like that. I think what you are wanting to do, is to terminate the loop when you have reached the end of line. So that index1 and index2 can get the length of the string input. If I were you, I would just use C++ builtin strlen() function for that. And in the first place, you should use C++ class string to handle strings. Also strings have a null - terminating character '\0' at the end of them. If you don't know about it, I suggest you take some time to read about strings.
Secondly, you have many bugs and errors in your code. The way you are reversing your string is not correct. Ask yourself, what are the contents of the arrays a and b at position which have higher index than the length of the string? You should use reverse() for reversing strings and arrays.
You have errors on adding loop also. Note, you are changing the arrays value when they are A, B, C, D, and so on for hexadecimal values with the corresponding decimal values 10,11,12,13 and so on. But you should change the values for the character '0' - '9' also. Because when the array holds '0' it is not integer 0. But is is ASCII '0' which has integer value of 48. And the character '1' has integer value of 49 and so on. You want to replace this values with corresponding integer values also. When you are also storing the result values in c, you are only handling only those values which are above 9 and replacing them with corresponding characters. You should also replace the integers 0 - 9 with there corresponding ASCII characters. Also don't forget to put a null terminating character at the end of the result.
Also, when p is getting larger than 15, you are only changing your carry, but you should also change p accordingly.
I believe you can reverse the result array c in a much more elegant way. By only reversing when the calculation has been performed totally. You can simple call reverse() for that.
I believe you can think hard a little bit more, and write the code in the right way. I have a few suggestions for you, don't use variable names like a,b,c,o. Try to name variables with what are they really doing. Also, you can improve your algorithm and shorten your code and headache with one simple change in the algorithm. First find the length of a and then find the length of b. If there lengths are unequal, find out which has lesser length. Then add 0s in front of it to make both lengths equal. Now, you can simply start from the back, and perform the addition. Also, you should use builtin methods like reverse() , swap() and also string class to make your life easier ;)
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main(){
string firstVal,secondVal;
cout<<"Input two hexadecimal numerals(both of them within 100 digits):\n";
cin >> firstVal >> secondVal;
//Adjust the length.
if(firstVal.size() < secondVal.size()){
//Find out the number of leading zeroes needed
int leading_zeroes = secondVal.size() - firstVal.size();
for(int i = 0; i < leading_zeroes; i++){
firstVal = '0' + firstVal;
}
}
else if(firstVal.size() > secondVal.size()){
int leading_zeroes = firstVal.size() - secondVal.size();
for(int i = 0; i < leading_zeroes; i++){
secondVal = '0' + secondVal;
}
}
// Now, perform addition.
string result;
int digit_a,digit_b,carry=0;
for(int i = firstVal.size()-1; i >= 0; i--){
if(firstVal[i] >= '0' && firstVal[i] <= '9') digit_a = firstVal[i] - '0';
else digit_a = firstVal[i] - 'A' + 10;
if(secondVal[i] >= '0' && secondVal[i] <= '9') digit_b = secondVal[i] - '0';
else digit_b = secondVal[i] - 'A' + 10;
int sum = digit_a + digit_b + carry;
if(sum > 15){
carry = 1;
sum = sum % 16;
}
else{
carry = 0;
}
// Convert sum to char.
char char_sum;
if(sum >= 0 && sum <= 9) char_sum = sum + '0';
else char_sum = sum - 10 + 'A';
//Append to result.
result = result + char_sum;
}
if(carry > 0) result = result + (char)(carry + '0');
//Result is in reverse order.
reverse(result.begin(),result.end());
cout << result << endl;
}

C++ Check and modify strings / String subscript out of range

I'm trying to make a program which modifies words in a specific manner:
It should first check the ending of the words and then proceed to modify them. I won't explain it in detail, because it doesn't make much sense in English.
I've written the following:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Por favor, introduzca los gentilicios separados por la tecla enter, para finalizar, escriba OK" << '\n';
string name[10];
string place[10];
for (int i(0); (i < 10); i++)
{
getline(cin, name[i]);
if (name[i] == "OK") //Error here
break;
}
for (int i(0); (i < 10); i++)
{
place[i] = name[i];
if (name[i][name[i].length() - 1] == 'c')
{
if (name[i][name[i].length()] == 'a' || (name[i][name[i].length()] == 'o') || (name[i][name[i].length()] == 'u'))
place[i][place[i].length() - 1] = 'q';
place[i][place[i].length()] = 'u';
place[i] = place[i] + "istan";
}
else if (name[i][name[i].length()] == 'a' || name[i][name[i].length()] == 'e' || name[i][name[i].length()] == 'i' || name[i][name[i].length()] == 'o' || name[i][name[i].length()] == 'u')
{
place[i][place[i].length()] = 'i';
place[i] = place[i] + "stan";
}
if (name[i][name[i].length()] == 's')
place[i] = place[i] + "tan";
else {
place[i] = place[i] + "istan";
}
place[i][0] = toupper(place[i][0]);
}
for (int i(0); (i < 10); i++)
{
cout << place[i] << '\n';
}
return 0;
}
Now I'm getting the error "String subscript out of range" . I would like to know where is the error exactly. I know it prompts when I write "OK", at line "18".
The condition i <= sizeof(name). sizeof(name) returns the size of the array in bytes, not the number of elements in it. Even if it returned the number of elements, <= is wrong and would cause an out-of-bounds access (should be <).
To loop through all elements in an array, you can use the range-based for-loop:
for(auto& n : name)
{
getline(cin, n);
if (n == "OK")
break;
}
Or to do it the right way with the C-style for-loop:
for (int i(0); i < sizeof(name)/sizeof(name[0]; i++)
{
…
}
Here:
for (int i(0); (i <= sizeof(name)); i++)
sizeof(name) is the size in bytes of the array, which as it is an array of std::string is effectively meaningless. If you want to iterate over 10 items, simply say so (note also that less-than-or-equals is also wrong here):
for (int i = 0; i < 10; i++)
And here:
getline(cin, name[i]);
whenever you perform input you must check the return value of the input function and handle any errors:
if( ! getline(cin, name[i]) ) {
// handle error somehow
}
And here:
string * p;
you do not want to be dealing with pointers to strings. If you want to access the contents of a string, you use operator[] or other string member functions on the string.
std::strings are not like cstrings. You can just grab a part of them using a std::string*. When you do
*(p+ (name[i].length()-2))
You actually say advance the address stored in p by name[i].length()-2 amount and access that string. If you go past the end of the name array then that is undefined behavior. If not you still haver a std::string which cannot be compared with a char. If you want to check if the string ends with "ca" then you can just use
if (name[i].substr(name[i].size() - 2) == "ca")
You're last loop is doing something quite funky. There's no need to go that far. You can just do something like:
if (name[i][name[i].length - 2] == 'c')
To compare the next to last character with c. And a very similar test to compare the last one with a.
To clarify why what you're doing is not OK, you first get p as a pointer to a string to the current element. Then you do some pointer arithmetic p + (name[i].length - 2), which still results in a pointer to a string. Finally, you dereference this, resulting in a string. Which you can't compare to a char. Moreover, the pointer was to some arbitrary address in memory, so the dereference would produce a string with very bad data in it. Quite arbitrary, one might say. If you tried to work with it you'd break your program
You seem to be working with the string as one would with a C-like string, a char*. The two are not the same, even though they represent the same concepts. A C++ string, usually, has a size field, and a char* pointer inside it, as well as a bunch of other logic to make working with it a char-m.
Because you aren't comparing against a specific char in the string, you're comparing against a string.
Considering the following bit of code:
*(p + (name[i].length() - 2))
This evaluates to a string because you are taking p (a string*) and concatenating a char to it. This means it's still a string (even though it's a one-character string), thus the other side of the equation won't be comparable to it.
What you need here instead is this:
if (name[i][name[i].length() - 2] == 'c')
Since name[i] is already a string, we can just get the char from it using the code above. This does return char, so it's comparable. This also allows you to get rid of the whole string* bit as it is not needed.
First, (i <= sizeof(name)) is wrong, it should be i < sizeof(name) / sizeof(*name). sizeof(array) return the size of array in bytes, you need to divide the size of an array's element to actually get the maximum element count of an array. If you find that complicated then use std::vector:
vector<string> name(10); //a vector of size 10
for (size_t i = 0; i < name.size(); i++) //name.size(), simple
Secondly, you need to keep track of how many strings in your name array. Or you need to check if name[i] == "OK" then break the second loop (similar to the first loop). name[i] after "OK" are invalid.
Thirdly, don't use *(p+ (name[i].length()-2)). If you want the second last character of name[i], you can write it as name[i][name[i].size()-2] or name[i].end()[-2] or end(name[i])[-2]
If you want to check if the word ends in "ca", then you can use substr:
if (name[i].substr(name[i].size() - 2) == "ca")
{
//...
}

Assertion Error using a struct vector c++

I have a program where I want to update a variable from a string. The function will read in a string, find if it is addition, subtraction, etc. and then add it to the variable. The function is this:
using namespace std;
struct variable{
string name;
int value;
};
void update_varabile(string line, vector<variable> & v)
{
char c = line[0]; //variable to be updated
string b;
char d[0];
int flag = 0; //counter
int a = 0;
int temp_value = 0;
int perm_value = 0;
for (int i = 0; i < v.size(); i++) {
if (c == v[i].name[0]) {
flag = 1;
temp_value = v[i].value;
break;
}
}
if (flag == 1) { //variable is present
for (int i = 0; i< line.size(); i++) {
if (line[i] == '+'|| line[i] =='-'|| line[i] == '*'|| line[i] =='/') {
b[0] = line[i+1]; //assuming the integer is between 0 and 9
d[0] = b[0];
a = atoi (d);
if (line [i] == '+') {
perm_value = temp_value + a;
} else if (line [i] == '-') {
perm_value = temp_value - a;
} else if (line [i] == '*') {
perm_value = temp_value * a;
} else if (line [i] == '/') {
perm_value = temp_value / a;
}
}
}
for (int i = 0; i < v.size(); i++) {
if (v[i].name[0] == 'c') {
v[i].value = perm_value;
break;
}
}
}
}
The call in main looks like this:
int main()
{
variable a;
int val = 0;
string up = "c=c+2";
string f = "c";
vector<variable> q;
a.name = f;
a.value = val;
q.push_back(a);
update_varabile(up, q);
return 0;
}
However, when I run the code, I get this error message:
Assertion failed: ((m_->valid == LIFE_MUTEX) && (m_->busy > 0)), file C:/crossdev/src/winpthreads-git20141130/src/mutex.c, line 57
Process returned 1 (0x1) execution time : 0.014 s
Press any key to continue.
I have run the debugger line by line and it shows that the function properly executes. I have also tried to look for that C:/ file on my computer and it doesn't exist. Not sure why this isn't working.
First thing first, get rid of all the breaks. Only place breaks should be used in C++ is at the end of each case statement. Makes near impossible to read code with a bunch of breaks, because I have to go down and figure out what each break is there and why. If you need to get out of a for loop early, then use a while loop. you don't need breaks at the end of if and else statements because they cause the program to leave a function early, your if and else statements will naturally skip over if you are using if, else if, and else condition formatting.
Now having said that, you need to break down better what you are trying to do.
example you get a string value like this.
2+3+4-5+6
Your program is going to read from left to right. I am assuming you want it to take the first value which is two and then add three to it then four and so on and so fourth.
The way to do this is first parse the string for int values and then parse the addition and subtraction values. In other words read the int values out of the string untill you hit a value that is not between 0 and 9. Then see if that non-numerical value is an operator you are looking for. This way your program wont trip up on a value like 2555 and 2.
IE
//intValueHolder is a string.
while(i < line.size() && line[i] >= '0' && line[i] <= '9' ) {
intValueHolder.push_back(string[i]);
}
Then when you hit a '+' or something like that put the char value through a case statements. and don't forget to add a default value at the end to account for garbage input like 'a'. You may want to hold the value just incase you need to get your left side value first before you can get your right side value. But it sounded like you start out with a left side value so you really only need to find right and which operator it needs. I'm not going to rewrite your program because this looks like an assignment for school. But I will point you in the right direction. Let me know, if I was off on understanding your question.
You may also want to look into using queues for this, if you are not being restricted to just strings and vectors.

Reading a list of characters and storing in an array

I am having issues with the following code and I cant figure out why out of loop is not being printed. With this code I want the program to ignore any spaces inputted by the user and after a space is inputted the number previously entered is stored in an array location. Like this I want 6 and 78 to be stored in 2 array locations not store them individually as 6 7 8.
This is my code:
while ((in=getchar()) != '0')
{
if (in == ' ')
{
printf("space\n ");
continue;
}
else
{
printf("assigning\n ");
input[i]=in;
}
i++;
}
printf("Out of Loop");
My output when inputting 5 6 78 is:
assigning
space
assigning
space
assigning
assigning
assigning
With this output I doubt whether 78 is being stored in one memory location.
I would really appreciate your help,Thankyou
C++:
std::vector<int> v;
std::string s;
int i;
std::getline( std::cin, s); // read full line with whitespaces
std::istringstream iss( s); // prepare to process the line
while( iss >> i) v.push_back( i); // read into i and push into vector if
// operator>> was successful
C:
int array[ 10];
int i = 0, retval;
while( i < 10 && ( retval = scanf( "%d", &array[ i++])) == 1) ;
if( i == 10) {
// array full
}
if( retval == 0) {
// read value not an integer. matching failure
}
if( retval == EOF) {
// end of file reached or a read error occurred
}
You are deciding character by character. Thus, you will only store single digits or ignore those digits.
You could store the whole numbers like this (extending your code):
bool currentNumberStarted = false;
int currentNumber = 0;
int idx = 0;
while ((in=getchar()) != '0')// you probably want '\0' instead of '0'
{
if (in == ' ')
{
if (currentNumberStarted)
{
input[idx]=currentNumber;
idx++;
currentNumberStarted = false;
}
printf("space\n ");
continue;
}
else
{
printf("assigning\n ");
currentNumberStarted = true;
currentNumber *= 10;
currentNumber += in;
}
}
printf("Out of Loop");
First of all I highly doubt that your while loop will ever end, even if you made that to '\0' ,Because you are using char variable to store input. Not strings, Only strings uses '\0' at the end,How can we enter '\0' from keyboard..???. even if you want to keep it as '0',you would alwasy have to enter 0 as last number to end the loop(which i think you dont want to.)
So the Solution is this:-
After Entering Numbers You will Hit ENTER key, which would generate a newline character '\n' so you have to check for new line character('\n'), And as you are using getchar() function, it will returns EOF (-1) at the end of input, so its important to check for it too.So you have to check for both '\n' and EOF at once in while loop.And at last you should also check for array index number(it should be less than 1) in which you are storing numbers.
I made some effort to make you understand the program in comments.
int main()
{
int i=0;
int input[10]={0}; //here only 10 integers can be entered(hence i should be i<10)
int in; //To store input character
int num=0; //To store number which is converted from character.
int new=1; //To check if new number is started 0=false 1=True.
int count=0;//This is just to know how many numbers entered,also used to print numbers at end.
while ((in=getchar()) != '\n' && (in!=EOF) && i<10)//should check for both '\n' and EOF and array index also
{
if (in == ' ')
{
printf("space\n ");
if(new==0) //if new Number is not started yet.
{
new=1; //Start of a New number.(a number entered after space)
i++; //As new number is started it should be stored in new array index.
}
continue; //if space is entered just go to begining
}
else
{
printf("assigning\n ");
num=in-48; //converts a character to number (ex:- converts '3' to 3)
input[i]=(input[i]*10)+num; //storing the number..This is important do a paper work to understand this step.
new=0; //still in same number(we are still processing same number)
}
}
printf("Out of Loop \n");
count=i+1; //This gives correct count of numbers entered
for(i=0;i<count;i++) //to print numbers.
printf("%d ",input[i]);
return 0;
}
OUTPUT:-
E:>example.exe
78 2 65 998 1
assigning
assigning
space
assigning
space
.
.
.
space
assigning
Out of Loop
78 2 65 998 1