Char to Int - C++ - c++

I know there are already answered questions about it, but I have read most of them and still couldn't solve my problem.
I have a program that will read notes, keep them in a list and give options to the user to delete, change, or select a specific note.
I'm using this struct:
struct List {
char title [101];
char text [501];
int cont; //code of the note.
struct List* next;
};typedef List list;
I'm stuck at the point of selection, if the user types a * it must return all notes, and if the user type a number it must return only the corresponding note.
So far i just have this:
List* select (List *l, int v) {
List *p = l;
for (p = l; p != NULL; p = p -> next){
if( p -> cont == v){
cout << "\nTitle: " << p -> title << "\n";
cout << "Text: " << p -> text << "\n";
cout << "Code: " << p -> cont << "\n" << "\n";
}
}
how can I read a symbol in char and transform to int, to compare it with the code of the note.
sorry if i write something wrong, i'm brazilian and i have none practice for writing.
EDIT:
Thank you so much guys, it realy realy helped me a lot and now i get to finish my work! :D

Try this:
Get the input as a string
string str;
cin >> str;
If the string is a *
if (str == "*")
{
// print out all notes
}
Else, attempt too convert string into number with strtol. Strtol gives better error checking than atol because it tells you whether the whole string was converted and if not, where so you can go look.
char * endp;
long code;
code = strtol(str.c_str(), // the string converted to characters
&endp, // where in the string the number ended.
10); // the base of the number, base 10 in this case for
// decimal. 16 if you want to input in hex.
// Unlikely in this case.
if (*endp == '\0') // If the number didn't end didn't end at the end
// of the string, the number is invalid
{
// print note for code
}
A quick note on strtol(str.c_str(), &endp, 10); and testing endp.
This doesn't actually work. endp winds up pointing at a memory location that may not be valid by the time you get to check. Really, you need to get the char array out of the string and into something for which you can guarantee the scope.
The above warning is incorrect based on old, or faulty data. Thank you #TamásSzabó. Makes future code writing a wee bit simpler.
No std::string version is almost the same:
char str[64]; // allocate storage for a big number.
cin.get(str, sizeof(str)); // read up to size of string -1 and null terminate
if ((str[0] == '*') && (str[1] == '\0'))
// first character in string is '*' and there
// is no second character
{
// print out all notes
}
else
{
char * endp;
long code;
code = strtol(str,
&endp,
10);
if (*endp == '\0') //this time endp will be valid
{
// print note for code
}
}

If you really need to only char and int types, you could try this:
char buf[10]; // Assuming that you won't have more than 10 characters in your number
char *endp;
cin >> buf; // This may cause you problems if the input string is more than 9 characters long!
From here on you can use user4581301's answer:
if ( (buf[0] == '*') && (buf[1] == '\0') )
{
// Print all your notes here
}
code = strtol(but, // the string converted to characters
&endp, // where in the string the number ended.
10); // the base of the number, base 10 in this case for
// decimal. 16 if you want to input in hex.
// Unlikely in this case.
if (*endp == '\0') // If the number didn't end didn't end at the end
// of the string, the number is invalid
{
// print note for code
}

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.

Using pointers to find positions of characters between unbalances parentheses

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

`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

odd output from char array

I am currently writing a command line "parser" so to speak, and so far it has been working until I tried a few ways to add options/parameters.
void parser::nextCom() {
cout << parser::prompt; // parser::prompt = "> "
string com;
getline(cin, com);
char the_command[5]; // i want this to store the command e.g. "go" given that go is a command
for (int i = 0; i < com.size(); i++) {
if (com[i] == ' ') break;
else the_command[i] = com[i];
}
cout << the_command << endl;
}
The command is copied but some very unwanted characters show up when in print the_command to the console.
This is what I get if I pass "go north" as a command:
goÌÌÌÌÌÌÌÌÌÌÌÌÌÌØNi
I am not too sure about char arrays in C++, but I don't know how I am getting this output. Any help at all will be appreciated. Any questions about the code or if you need more of my code, just comment, thanks in advance
cout << the_command << endl;
When you print a char array like this, characters continue to be inserted until the null character \0 is found in the string.
Before you start copying characters from com to the_command, the array is completely uninitialized. I'll represent these unknown characters with question marks (but of course, they're probably not actually question marks):
? ? ? ? ?
This means you have no idea what the values of the chars in the array will be. You then copy only the characters g and o from the_command into com, so your array now contains:
g o ? ? ?
So when you attempt to output this array, the output stream doesn't know when to stop. You need to make sure you insert an \0 after the o. One way to do that would be:
for (int i = 0; i < com.size(); i++) {
if (com[i] == ' ') {
the_command[i] = '\0';
break;
}
else the_command[i] = com[i];
}
This will leave the array like so:
g o \0 ? ?
However, you'd be much better off just sticking to std::string. I don't want to think about the trouble you'll have with this array that could just be avoided. Here's how I would write your function:
void parser::nextCom() {
std::cout << parser::prompt;
std::string command_line, command;
std::getline(cin, command_line);
std::stringstream command_line_stream(command_line);
command_line_stream >> command;
if (command == "go") {
std::string direction;
command_line_stream >> direction;
go(direction);
}
}
You're not null-terminating the_command after the last character is read. Or doing any bounds checking.
Please, use std::string instead.
Change the code to:
if (com[i] == ' ')
{
com[i] = '\0';
break;
}
This will ensure there is a null terminator at the end of your char array. The reason you are seeing garbage is because std::cout will happily print characters until it sees a null terminator.
this is because you have a buffer overflow in your code. you copied an indeterminate length string into a char[5] buffer... basically, your loop is copying as many bytes as determined by the input string, into past the end of the char[5] array, which is no longer null terminated, so "cout" is just reading until it finds null bytes.
Basically the_command[5] contains garbage since is not initialized and doesn't contains the character terminator. You can clear it first, and you'll be fine
for (i = 0; i < 5; i++) {
the_command[i] = 0;
}

String reversal with pointers C++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why do I get a segmentation fault when writing to a string?
I want to write a simple C++ function that reverses a
string/char[] by only pointer arithmetic. I understand the concept
and have code already typed up.
I have the following .cpp file:
#include <iostream>
using std::cout;
using std::endl;
void reverse(char* target) //Requirements specify to have this argument
{
cout << "Before :" << target << endl; // Print out the word to be reversed
if(strlen(target) > 1) // Check incase no word or 1 letter word is placed
{
char* firstChar = &target[0]; // First Char of char array
char* lastChar = &target[strlen(target) - 1]; //Last Char of char array
char temp; // Temp char to swap
while(firstChar < lastChar) // File the first char position is below the last char position
{
temp = *firstChar; // Temp gets the firstChar
*firstChar = *lastChar; // firstChar now gets lastChar
*lastChar = temp; // lastChar now gets temp (firstChar)
firstChar++; // Move position of firstChar up one
lastChar--; // Move position of lastChar down one and repeat loop
}
}
cout << "After :" << target << endl; // Print out end result.
}
void main()
{
reverse("Test"); //Expect output to be 'tseT'
}
I've stepped through in the debugger several times but each time it
crashes around the temp = *firstChar line in the while loop. It
freezes up here and causes the program to stop running and unable to
finish. Is there something I am simply overlooking or is there
something deeper as to why I can't do it this way.
EDIT: There is an else condition, but I removed it for the sake of
brevity. It was after the if statement and it just prompted that the
word was 1 char or no word was put.
The problem is not in the reverse function, but in the calling code.
reverse("Test");
String literals are read-only, attempting to modify one leads to undefined behavior. Pay attention to compiler warnings (or turn the warning level up if you aren't getting any). The line above should be generating warnings about a deprecated conversion from const char * to char * being performed.
To fix the code:
int main() // <-- note the return type, int NOT void!
{
char str[] = "Test";
reverse( str );
}
This code will reverse it twice. Divide the loop by two.