Using pointers to find positions of characters between unbalances parentheses - c++

I am given a C++ programming problem: In a string I need to find wether or not there are balanced parentheses. If not, using pointers I should find position of the characters between unclosed parentheses (between second opening and nearest closing).
The problem statement is a bit confusing, I know. I think it should work somehow like that:
Input #1:
((aba)aaab)
Output:
OK.
Input #2:
(aa(a)ab
Output:
Parentheses not balanced: between characters 1 and 6.
Code below solves part of problem with the closed parentheses check and also there is a structure to keep the address of the opening parenteses. I am not sure how exactly to use pointers for that purposes, some attempts did not give any result, so I need some help here.
#include<iostream>
#include<string>
#include<stack>
using namespace std;
struct br_data{
char br_t;
char *cptr; //store the address of the opening parenthesis
};
int main (){
string input;
int addr;
br_data br;
getline(cin, input);
stack<br_data> braces;
char *a = input[0];
auto init_char = static_cast<void*>(&a); //store the address of the first character in the input string
cout << static_cast<void*>(&a) << endl; //gives the address in memory
for(auto c: input) {
if (c == '(') {
br.br_t = c;
br.cptr = &c; //storing the address of the first parenhesis
braces.push(br);
} else if (c == ')' ) {
if (braces.empty())
cout << "This line does not contain unclosed parentheses\n";
if (!braces.empty())
braces.pop();
}
}
if (!braces.empty()){
//int addr = br.cptr;
cout << "This line does not contain unclosed parentheses\n";
//int pos = (&br.cptr) - (&a); //how to calculate the position??
cout << "Position of the second opening parenthis is " << () << endl;
//cout << "Position of the nearest closing parenthis is " << -how?? (static_cast<void*>(&br.cptr)) << endl;
}
if (braces.empty()){
cout << "Parentheses are balanced in this line\n";
}
return 0;
}

When you write
br.cptr = &c; //storing the address of the first parenhesis
you're actually storing the address of a local object of char type declared earlier:
auto c: input
By the moment you exit the loop it is officially dangling.
One simplest solution would be to actually consider string's characters, not their local copies:
for(auto &c: input) {
(and, even better, change auto into char for better clarity keeping source length the same). Then you can go on and see how your solution needs to be fixed further.
(A few extra free advice: input[0] is a rvalue reference of type char so it makes no sense to assign it to a variable of type char *, and what you try to do in that line is actually written as char *a = input.c_str(); or input.data() or even &input[0], pick the best option; and br.cptr is of type pointer-to-char already, so the character's position in a string would be calculated as br.cptr - a, you need to subtract the pointers themselves, not their addresses.)

#include <iostream>
using namespace std;
int main(){
char str[]="Hello Programming";
char *ptr;
char ch;
char s;
s='n';
ptr=str;
cout<<"To be found Character"<<endl;
cin>>ch;
while(*ptr++ != '\0')
if(*ptr==ch)
s='y';
if (s=='y')
cout<<"FOUND";
else
cout<<"not found";``
return 0;
}

Related

How to locate and remove these symbols from my reversed string

This is an oddly specific problem but I need help because I am very confused. I am trying to use pointers to ask a user to input a string and the output will print the reverse. So far I have used a reverse function and applied the pointers. Here's what the code looks like right now:
#include <iostream>
using namespace std;
void reverse(char name[])
{
char *p;
p = name;
while (*p != '\0')
{
++p;
}
while (*p >= 0)
{
cout << *p;
--p;
}
}
int main()
{
char name[100];
cout << "Please enter a string: ";
cin.getline(name, sizeof(name));
cout << "The reverse of the string is: ";
reverse(name);
return 0;
}
When I run the program, it works but there is one problem. For example the inputted string is Stack Overflow, this is the result:
Please enter a string: Stack Overflow
The reverse of the string is: wolfrevO kcatS ►☺ ◄ a
As you can see there are these symbols that show up in the final output. I have tried locating where it comes from and I think it is because of the pointers because when I used an array for the function, it properly printed the reversed string without the symbols. I am asking if there is a way for me to remove these symbols while still using pointers? I have tried multiple variations on making the function with the pointers but the symbols still print at the end.
That garbarge happens because you don't have null terminating character at the beginning of the string, thus you don't terminate when going backwards. I modified your code to keep sentinel zero character at 0-th position, and now your code works without bugs.
Also condition while (*p >= 0) should be replaced with while (*p).
Try it online!
#include <iostream>
using namespace std;
void reverse(char name[])
{
char *p;
p = name;
while (*p != '\0')
{
++p;
}
--p;
while (*p)
{
cout << *p;
--p;
}
}
int main()
{
char name[100];
name[0] = 0;
cout << "Please enter a string: ";
cin.getline(name + 1, sizeof(name) - 1);
cout << "The reverse of the string is: ";
reverse(name + 1);
return 0;
}
Input:
Please enter a string: Stack Overflow
Output:
The reverse of the string is: wolfrevO kcatS
When you use
while (*p >= 0)
{
cout << *p;
--p;
}
you seem to assume that the space just before the beginning of the array is occupied by something negative; this is not a safe assumption, and the loop can iterate past that point, printing whatever binary junk happens to be in that region of memory. I say it can, because dereferencing a pointer into unallocated space like that is undefined behavior. It can do anything; it can terminate the loop so that the program appears to work correctly, it can print gibberish, it can crash you computer.
If you want to stop at the beginning of the given string, look for the beginning of the given string:
do
{
--p;
cout << *p;
}
while (p != name);
You're reading 100 characters into the string, which means there's a chance some trash input buffer values will be read too. This is where the symbols come from. Since you're using char arrays, maybe instead of getline use something like this:
char c = getchar();
int i = 0;
while(c != '\n'){
name[i] = c;
c= getchar();
i++;
}
name[i++] = '\0'
This way you'll only read what you need to read, and will have the terminating character '\0' at the end of the string. Bear in mind there's probably a cleaner solution using getline tho. Either way, the problem is that you're reading more values then you want to read into the char array, and since you're directly accessing memory you need to figure out a way to add a '\0' after the desired string, so the method knows when to stop - I'm guessing char arrays are implemented in such a way to secure this always happens, hence the reason it works with char arrays but not with pointers.

Output is not as expected

The idea of my program was to print individual digits of n.
But instead it prints all the digits at once in the first line and a bunch of zeroes or garbage values in subsequent lines.
I want to access each individual number as we can do with arrays.
Suppose the input is 1234, why doesn't it print 1\n2\n3\n4?
#include <iostream>
#include <cmath>
#include <stdlib.h>
using namespace std;
int main()
{
int* n=(int*)malloc(1000*sizeof(int));
cin>>*n;
int len;
len = log10(*n) + 1;
for(int i=0;i<len;i++)
{
cout<<n[i]<<endl;
}
}
n is declared as a pointer to a memory location which can store 1000 integer entities. When you use cin>>*n;, an integer value is read as input and store at the first memory block among the 1000 blocks. The individual digits of the integer are not stored in separate blocks, hence you can't print them separately.
For example, if the input is 123,
n[0] stores 123, n[1],n[2],...n[999] stores junk values.
To store a value in n[1], you will have to use cin again.
For some reason you think that
int* n=(int*)malloc(1000*sizeof(int));
cin>>*n;
will read a number and put each digit in a different element of the dynamic array n. If that happened then the rest of your code would work (kind of). But of course it doesn't. Instead the number read is put into *n (or, same thing, n[0]) and the rest of the dynamic array elements are uninitialised, which explains the garbage values you see.
I'm struggling to understand why you thought your code might behave in the way you wanted. I guess you are just an optimistic person and think that if you wish hard enough the compiler will understand. This seems to be quite a common attitude among beginners. Unfortunately programming isn't like that.
When you cin >> *n, you don't read the number digit by digit, but read in as a whole.
So when you cin >> *n and type in 1234, *n becomes 1234.
If you want to print all the individual digits, like 1\n2\n3\n4, you need to separate the digits for yourself:
int pos = 1;
while (*n != 0)
{
n[pos] = n % 10;
n /= 10;
++pos;
}
for (--pos; pos > 0; --pos)
{
cout << n[pos] << endl;
}
However, the easiest approach is to read in the number as a string, not a number, then print out the characters, that is the digits, one by one.
char str[1000];
cin >> str;
for (char *s = str; *s; ++s)
{
cout << *s << endl;
}
You can also convert the number into a string, and do the same:
#include <cstring>
using namespace std;
...
char str[1000];
sprintf(str, "%d", *n);
for (char *s = str; *s; ++s)
{
cout << *s << endl;
}
------- Original Answer:
If you want to print the first element of n:
cout << *n;
or
cout << n[0];
Your code
for(int i=0;i<len;i++)
{
cout<<n[i]<<endl;
}
means
cout << n[0] << endl;
cout << n[1] << endl;
cout << n[2] << endl;
...
cout << n[len-1] << endl;

Using toupper on char returns the ascii number of the char, not the character?

int main()
{
char hmm[1000];
cin.getline(hmm, 1000);
cout << hmm << endl; //this was to test if I could assign my input to the array properly
for (int sayac = 0; hmm[sayac] != '#'; sayac++) {
if (!isdigit(hmm[sayac])) {
if (islower(hmm[sayac]))
cout << toupper(hmm[sayac]);
else if (isupper(hmm[sayac]))
cout << tolower(hmm[sayac]);
else
cout << hmm[sayac];
}
}
"Write a program that reads keyboard input to the # symbol and that echoes the input
except for digits, converting each uppercase character to lowercase, and vice versa.
(Don’t forget the cctype family.) "
I'm doing this exercise from the primer book. But when I run it, it returns the ascii order of the char, not the uppercase/lowercase version of the character. Couldn't figure out the problem. Can someone tell my why please?
(I may have other problems about the exercise, please don't correct them if I have. I want to fix it on my own (except the problem I explained), but I can't check the other ones as I have this problem.
When writing
std::cout << toupper('a');
the following happen:
int toupper(int ch) is called, and returns an integer whose value is 'A' (0x41).
std::basic_ostream::operator<<(std::cout, 0x41) is called, that is the int (2) overload since an int was provided.
Overall, it prints "65".
As a solution, you can cast back your upper case to a char:
std::cout << static_cast<char>(toupper('a'));
It's a question of representation. There is no difference between a character and that character's numeric value. It's all in how you choose to display it. For example, the character 'a' is just a constant with a value equal to the character's numeric value.
The problem you are having is that std::toupper and std::tolower return an int rather than a char. One reason for that is that they handle EOF values, which are not necessarily representable by char. As a consequence, std::cout see you are trying to print an int and not a char. The standard behavior for streaming an int is to print the number. The solution is then to cast your result to char to force the value to be interpreted as a character. You can use something like std::cout << static_cast<char>(std::toupper(hmm[sayac]));.
Try the following :
#include <cctype>
#include <iostream>
int main()
{
char hmm[1000];
std::cin.getline(hmm, 1000);
std::cout << hmm << std::endl; //this was to test if I could assign my input to the array properly
for (int sayac = 0; hmm[sayac] != '#'; sayac++) {
if (!std::isdigit(hmm[sayac])) {
if (std::islower(hmm[sayac]))
std::cout << static_cast<char>(std::toupper(hmm[sayac]));
else if (isupper(hmm[sayac]))
std::cout << static_cast<char>(std::tolower(hmm[sayac]));
else
std::cout << hmm[sayac];
}
}
}
You should also consider using an std::string instead of an array of char of arbitrary length. Also, take note that you have undefined behavior if the input string does not contain #.

Reverse string code using passing by reference method not working

Please tell me why my code to reverse the input string is giving me various errors.
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
void ReverseString(string &aString);
int main(){
string info;
cout << "What's your string?" << endl;
getline(cin, info);
ReverseString(info);
cout << ReverseString(string info) << " compare with: " << info << endl;
system("pause");
return 0;
}
void ReverseString(string &aString){
for(int i = 0; i < aString.length(); i++)
{
string temp = 0; // initialize temporary string
temp = temp + aString.at(aString.length() - 1 - i); // hold temporary string
if(i => aString.length()) /*assign temp string to aString when all chars are processed*/
{
temp = &aString;
}
}
}
Hi you could simplify your code a lot by using the STL
for example:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
std::string str = "Hello World";
cout << str << endl;
std::reverse(str.begin() , str.end());
cout << str << endl;
return 0;
}
let me know if this is not suitable to your needs as theres a few other ways to do it too.
Without STL:
There are some corrections/changes to your code required, which I have supplied below. However you may want to look at some documentation on referencing variables to get an idea of how it works, such as:
http://www.cprogramming.com/tutorial/references.html
http://www.thegeekstuff.com/2013/05/cpp-reference-variable/
http://en.wikipedia.org/wiki/Reference_(C++)
What is a reference variable in C++?
http://www.tutorialspoint.com/cplusplus/cpp_references.htm
Correct reference and pointer use is a major part of C++ and allows for some of the most powerful functionality in the language, provided it is used correctly, or major headaches and mental scarring if used incorrectly, so it is worth, even essential, to have a firm grasp of them.
And even then expect the odd misuse to crop up every-so-often. :)
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
void ReverseString(string &aString);
int main(){
string info;
cout << "What's your string?" << endl;
getline(cin, info);
cout << info << " compare with: ";
ReverseString(info);
cout << info << endl;
system("pause");
return 0;
}
void ReverseString(string &aString)
{
int len = aString.length();
string temp = aString;// initialize temporary string
aString ="";
for(int i = 0; i < len; i++)
{
aString += temp[len - (1+ i)]; // assigns the reversed value to the referenced string
}
}
Just noticed the quote below from #zac-howland : so true, I have however left the code in as an illustrative piece. Provided some reading is done on this as well as plenty of experimentation I hope NewProgrammer will get the information and skill-set he needs to go forward.
#include<iostream>
#include<string>
#include <algorithm>
using namespace std;
string info;
string rvrs(string &str)
{
std::reverse(str.begin(),str.end());
return str;
}
int main()
{
cout<<"What is your string :: ";
getline(cin,info);
cout<<rvrs(info);
cout<<endl;
return 0;
}
You have a few syntactical errors in addition to your logical ones:
cout << ReverseString(string info) << " compare with: " << info << endl;
ReverseString(string info) will pass in an empty string to your ReverseString function (if it even compiles - which looks like it should not since you have 2 info's in the same scope). What you wanted is:
cout << ReverseString(info) << " compare with: " << info << endl;
In your reverse function, you only need to go to length() / 2.
Since you are passing by reference, changes you make to the string within the function will be reflected in the object you passed into it. That is, the original info will be reversed. If you want it to operate on a copy, you need to pass it by copy, not by reference.
Finally, cout << ReverseString(info) is not useful (if it even compiles) as ReverseString returns a void. You should have it return a string (the reversed string).
You have a number of problems.
string temp = 0; // initialize temporary string
It doesn't really make sense to initialize a string to 0. Just string temp; would be fine here.
temp = temp + aString.at(aString.length() - 1 - i); // hold temporary string
That's not quite how I'd do things, but I guess it should work.
if(i => aString.length())
This condition doesn't seem to make sense. Your loop is defined to iterate with i going from 0 to the length of the string -1, so it can never be greater than or equal to the string length.
/*assign temp string to aString when all chars are processed*/
{
temp = &aString;
}
Here the code doesn't match the comment. The comment says you're going to assign to aString, but the code assigns something to temp. The comment is probably closer to what you really want. But you still need to fix the condition, and probably want to do this after the loop has finished executing. So in pseudo-code, you'd end up with something like:
for (all characters in the string)
add the next character in the string to the end of temp
assign temp back to the original string

`const char*' to `char'

I am new to programming and attempted to improve on my basic countdown timer. I don't know why I'm getting this error and other questions are in different situations and therefore don't suit my program.
//countdown timer using while loops, if else, strings and sleep
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
int main ()
{
char progend[5];
float a; /* a will be floating point */
cout << "Enter start the the number you want to count down from" << ".\n";
while (a>-1) { /* the main program is located here */
cin >> progend[5];
if (progend[5] = "end") /* if the user inputs end the program ends */
{
a = -1;
}
else if (progend [5] = "start")
{
cin >> a;
while (a>0) { /* the actual countdown timer*/
Sleep(100);
a = a - 0.1;
cout << a;
}
cout << "Finished!" << ".\n" << "Enter start then enter another number to count down from or enter end to close the program" << ".\n";
}
else
{
cout << "Enter yes or end";
}
}
return 0;
}
Any help would be appreciated.
char progend[5];
...
if (progend [5] = "start")
tries to assign string literal "start" to 6th character of progend array (which doesn't even exist). Note that even if this code tried to assign a character, writing into the array after its end would cause undefined behavior.
You could either use C-style strcmp:
if (strcmp(progend, "start") == 0)
or yet even better: since this is C++, use std::string objects instead:
std::string progend;
...
if (progend == "start") ... // <-- this will use std::string::operator==
You're trying to assign a char* to char, I'm assuming you want to compare .
So use strstr
if (strstr(progend,"end" )){
//...
}
Similarly all other places
But why not use std::string , when using C++
std::string progend;
if(progend.find("end") != std::string::npos)
{
}
You are assigning a const char * to a char variable in
if (progend[5] = "end")
progend[5] is an element of a char array that holds a char value. "end" cannot be assigned to it.
You can use std::string. Then compare it like
std::string progend;
...
if(progend == "end")
{
//your code
You made a number of different errors.
cin >> progend[5];
Here, you ask for a character input, instead of a string. What is more, index 5 is out of the bounds of the array (we start counting from 0).
progend[5] = "start"
Here, there are two errors. To compare for equality, you sholud use == instead of =. What you actually did is try to assign a value. What is more, "start" is a C-type String, or better a pointer to the first character of the String.
Why don't you simply use a String from the C++ STL?
#include <string>
using namespace std;
// etc.
String progend;
Also, replace all instances of progend[5] with progend, you are not refering to a specific position. Equality check must also be ==.
I hope this helps!!! :D