12 hour to 24 hour time conversion - c++

I am trying to write this c++ program from hackerrank but in my output all I am getting is a blank space.
The input string is in the form of HH:MM:SSpp where HH is an hour on two digits with leading zero, MM the minutes, SS the seconds and pp is either AM or PM.
#include <bits/stdc++.h>
#include<iostream>
#include<string>
using namespace std;
string timeConversion(string s)
{
string p;
int i,j;
if(s[8]==80){ // checking if it is AM or PM
int x = s[0]*10 + s[1] +12;
int y = x%10;
int z = x/10;
s[0]= z;
s[1]= y;
for(i=0;i<10;i++){
p[i]=s[i];
}
}
string newt= p.substr(0, p.size()-2); //removing last two characters
return newt;
}
int main()
{
ofstream fout(getenv("OUTPUT_PATH"));
string s;
getline(cin, s);
string result = timeConversion(s);
fout << result << "\n";
enter code here
fout.close();
return 0;
}
Is there some logical error? I know the other approach for this question but it would be great if anyone could help me with it.

The problem is with treating character digits (e.g. s[0]) as integer digits.
If you are certain you are dealing with digits, the way to do arithmetic with the characters is by subtracting the value of the character '0', like so: s[0] - '0'. The result will be the integral digit.

The main problem
In your timeConversion() function, you define a string p, which is initialized by the string default constructor to "".
Now for AM times, you skip the if and go directly to string newt= p.substr(0, p.size()-2);, which on an empty p will just create an empty newt string. So you return an empty value. Every time !
For PM times, you go into the if to do some transformations. Unfortunately p[i]=s[i]; doesn't do what you think. In fact it is out of bound access in the empty p string. And in the end, the length of p will still be 0 which will cause an empty value to be returned (in the best case).
The start of a solution
Initialize p at construction:
string p=s;
The code will then immediately work for AM strings. For PM strings, you still need to take into account uv_ 's answer related to ascii vs. binary math.
Here the result:
string timeConversion(string s)
{
string p=s;
int i,j;
if(s[8]=='P'){ // checking if it is AM or PM
int x =(s[0]-'0')*10 + (s[1]-'0') +12;
p[0]= x/10 +'0';
p[1]= x%10 +'0';
}
return p.substr(0, p.size()-2); //removing last two characters
}
Note: this assumes that the entry format will always be valid, and no space will be used instead of a leading 0.
Important Note: This code will fail on hackerrank, because it transforms 12:15:00pm into 24:15:00 and not in 12:15:00. Furthermore 12:00:00am will be tranformed in 12:00:00 instead of 00:00:00. More on wikipedia. Online demo about how to address these special cases

This code will work considering all test cases, just added two more conditions.
string timeConversion(string s)
{
string ans=s;
if(ans[8]=='P')
{
int x = (ans[0]-'0')*10+(ans[1]-'0')+12;
//cout<<x;
if(x!=24)
{
ans[0]=x/10+'0';
ans[1]=x%10+'0';
}
}
if(ans[8]=='A')
{
int y=(ans[0]-'0')*10+ans[1]-'0';
if(y==12)
{
ans[0]='0';
ans[1]='0';
}
}
return ans.substr(0, ans.size()-2);
}

Related

Null terminator carrying through when indexing string

I am trying pull specific characters from a string array, and assign them to defined indices in a new variable. I am having issues with what I expect is the null terminator, as there appear to be random assortment of undefined characters at the end of my strings.
I am new to coding in C++, and lower level programming in general. Note that the function "charBi" works perfectly, but it no longer works when assigning the output of "charBi" to the variable "binar" in the "strBi" function. I realize the code is probably not great, but any help is welcome, especially as it relates to getting rid of the random characters at the end of my "binar" string.
Thanks!
#include <iostream>
#include <array>
using namespace std;
//Program meant to output a string of binary for an input word or phrase
//library of letter and binary pairs
char letterNumber[27][10]={"A01000001","B01000010","C01000011","D01000100","E01000101","F01000110","G01000111",
"H01001000","I01001001","J01001010","K01001011","L01001100","M01001101","N01001110",
"O01001111","P01010000","Q01010001","R01010010","S01010011","T01010100","U01010101",
"V01010110","W01010111","X01011000","Y01011001","Z01011010"," 01011111"};
//finds binary number associated with input character. One character input
string charBi(char inputVar){ //WHY DOES THIS ONLY WORK IF THE FUNCTION IS A STRING?
//loop setup
int n=0;
int last=sizeof(letterNumber)/sizeof(letterNumber[0]); // equal 27
//loops through each of the strings in letterNumber
while (n!=last) {
if (letterNumber[n][0]==inputVar){ // if the letter is equal to input letter
char bina[8]; //number of numbers following a letter
for(int i=1;i<9;i++){ // writes the number associated with the letter to bina
bina[i-1]=letterNumber[n][i]; // assigns number to specific index
}
return bina; //BINA DEFINED AS CHAR, BUT OUTPUTTING AS STRING
}
n++;
}
}
//forms binary string of numbers for input phrase
string strBi(string strg){ //WHY DOES THIS ONLY WORK IF THE FUNCTION IS A STRING?
char binar[8*strg.length()]; //binary for each character is 8 numbers long
for(int i=0;i<strg.length();i++){ // for every letter in the input phrase
string chbi=charBi(strg[i]); //gets binary for individual letter from charBi function
cout<<"charbi sends: "<<chbi<<endl; //for debugging
for(int n=0;n<8;n++){ //for every 1 or 0 in the binary for an idividual letter
binar[(8*i)+n]=chbi[n]; // assign in order to string binar
}
cout<<"binar updates to: "<<binar<<endl; //for debugging
getchar(); //for debugging
}
return binar; //BINAR DEFINED AS CHAR, BUT OUTPUTTING AS STRING
}
int main(){
cout<<"final string is: "<<strBi("HELLO WORLD");
return 0;
}
Since you didn't properly terminate your arrays, the program is undefined.
In order to store a k-letter string, you need to use a k+1-element array and terminate it – char bina[9] = {}; and char binar[8*strg.length() + 1] = {}; should do the trick.
But you can simplify things a bit by leaving C behind:
std::map<char, std::string> letterNumber =
{{'A', "01000001"},
{'B', "01000010"},
// ...
{' ', "01011111}"}};
//forms binary string of numbers for input phrase
std::string strBi(const std::string& strg)
{
std::string binar;
binar.reserve(8 * strg.size());
std::for_each(strg.begin(), strg.end(), [&binar](char c) { binar += letterNumber[c]; });
return binar;
}
Make binar one character longer (char binar [8 * strg.length() + 1];) and set the last character to NUL (just before returning, do binar[8 * strg.length()] = '\0';)

Why is isdigit() not working?

Code:
#include <iostream>
#include <string>
using namespace std;
string s1,s2,s3,s4,s5;
int ex(string s){
int i;
if(isdigit(s)){
i = atoi(s.c_str);
}
else
return -1;
return i;
}
int main(){
int t;cin>>t;int v1,v2,v3;
while(t--){
cin>>s1>>s2>>s3>>s4>>s5;
v1=ex(s1);
v2=ex(s2);
v3=ex(s3);
if(v1<0) v1=v3-v2;
if(v2<0) v2=v3-v1;
if(v3<0) v3=v1+v2;
cout<<v1<<" + "<<v2<<" = "<<v3;
}
}
return 0;
}
Error:
error: no matching function for call to 'isdigit(std::string&)'
if(isdigit(s)){
I tried searching all the previous posts regarding this but still could not figure out why isdigit(s) function is not working.
And the question is there will be input of the form
47 + machula = 53, where machula is some word
and output should be 47 + 6 = 53.
isdigit is meant to check whether a single character is a digit or not, not a string. That's why the call isdigit(s) fails to compile.
You could use std::stoi. However, keep in mind that it will throw an exception if no conversion could be performed by the function.
try
{
i = std::stoi(s);
}
catch ( ... )
{
// Deal with the exception
}
You could also check whether the first character of the string is a digit before attempting to use std::stoi.
if ( !(s.empty()) && isdigit(s[0]) )
{
i = std::stoi(s);
}
NB
From the comment by #RemyLebeau:
The above check because that does not guarantee that all characters in the string are digits. std::stoi() parses the entire string and then reports the index of the first non-digit character, even if that is the null terminator. It also skips leading whitespace, so checking the first character may cause a false result where std::stoi() would have normally succeeded.

stream buffer (cin, getline, etc)

Is there a way to have the user input a line of characters to the stream buffer and then store them in different variables (of different types)?
For example, the user writes this sum of fractions:
1/5 + 2/7
I have 5 variables:
int numerator1, denominator1, numerator2, denominator2; char operat;
and after doing a fancy piece of code that i don't know, in the end, the variables will have stored the following
numerator1 = 1
denominator1 = 5
operat = +
numerator2 = 2
denominator2 = 7
Any suggestions?
You should definitely use the ASTs as they would help you parse the errors. But if you are looking for a simple parsing capabilities you can consider using sscanf. PS: Posting it as an answer due to reputation problem.
#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
char s[1024];
scanf("%s", s);
int n1, n2, dn1, dn2;
char op1, op2, op3;
sscanf(s, "%d%c%d%c%d%c%d", &n1, &op1, &dn1, &op2, &n2, &op3, &dn2);
cout<<"\n"<<n1<<" "<<op1<<" "<<dn1<<" "<<op2<<" "<<n2<<" "<<op3<<" "<<dn2<<endl;
}
Well, I am not sure of the specific algorithms, to attain this functionality, But i can suggest the following.
instead of using multiple variables, Take an integer array and a character array.
Take the input from the user in a string.
Loop through the character string and perform the following.
If, the value at current index is a num, Iterate counter until you
find a space or an operator (+/-*)
Extract the sub sting of it and store it in int array at the
corresponding index.
if the value at an index is an operator, store it in char array.

Writing a postfix calculator with a stack and iterator

#include <iostream>
#include <stack>
#include <string>
using namespace std;
int main()
{
string blah("512+4*+3−");
stack<int> astack;
int a=0;
int b=0;
int result=0;
int final=0;
for (string::iterator count=blah.begin(); count != blah.end(); count=count+1)
{
if (isdigit(*count))
{
astack.push(*count);
cout<<" "<<*count<<" ";
}
else
{
a=astack.top();
astack.pop();
b=astack.top();
astack.pop();
if(*count=='+')
{
result = a+ b;
}
else if (*count=='-')
{
result=a-b;
}
else if(*count=='*')
{
result=a*b;
}
astack.push(result);
}
}
final=astack.top();
cout<<final;
}
My problem is whenever I run it, the code seems to segment fault. When I tried running it with the operator commented it the stack seems to pop two values and I'm not really sure why
As PaulMcKenzie pointed out, your minus sign in the blah string is some sort of weird unicode character that looks like a normal minus sign, but it isn't. Since it's some weird unicode character, it is actually being stored in more than one byte in the string's memory, meaning your iterator for-loop is iterating more times than you would expect!
Put a cout << blah.length() << endl; right after you declare blah, and you'll see that the length is more than the expected 9 characters.
Also, this program will not output the right answer even when the problem above is fixed. You need to convert your ascii number characters (which are in the integer range [48,57]) to the equivalent integer values before you do any calculations with them.
If the code you posted is the actual code, then there is an issue with the string you posted.
string blah("512+4*+3−");
That last character after the 3 is not an ASCII minus sign. It is a Unicode character 0x2212. Change this to an ASCII minus and rerun the program.
What may have happened is that you started out with an ASCII minus, copied the text to another app, and the app tries to "fancy up" the minus by replacing it with more aesthetic looking character. Then you may have copied the text from this app back to your source code editor.

ASCII and isalpha if statement issue

I am writing a program that takes a user inputted character, such as A, and a user inputted number, such as 7. The program checks the validity of the character, if true runs thru till it gets to this loop inside of a function. I am using ascii decimal for this loop inside of a function. This loop needs to check isalpha and if it is run the code inside the {}'s, it's doing that correctly. The else is not working the way I want and am not sure how to correct it. I need the else (is not alpha) to add a 1 back to the counter in the loop and increase the ascii by 1. If I run it as so, it gives off a retry/ignore/abort error. If I run it without the num++; it runs and stops after the loop ends. So, if you put in a Z and choose 3, it runs thru the loop 3 times and outputs just a Z. Any thoughts on how to fix this?
I need it to output something like: Input: Z Input: 4 it should output: Z A B C to the screen. It needs to ignore other ascii non alpha characters.
Thanks
string buildSeries(char A, int num)
{
//builds the output with the info the
//user inputted
stringstream str1;
string outted;
int DeC=(int)A, i = 0;
//loop builds the output
for(i=0;i<num;i++)
{
if (isalpha(DeC))
{
//converts the decimal to a letter
str1<<(char)DeC;
//adds a space
str1<<" ";
//increases the decimal
DeC++;
}
else
{
num++;
DeC++;
}
}
//builds the sstream and puts it in
//variable "outted"
outted = str1.str();
return outted;
}
If you need to loop back to 'A' at Z change your DeC++ to
if DecC == 'Z'
DecC = 'A'
else
DecC++;
Or you could get fancy and use the modulus operator
Edit
I think the problem may be that this stringstream insertion operator, >>, doesn't have an overload that handles a char. It's converting the char to a short or an int then inserting it. Try using string::append(size_t size, char c) instead. That should handle inserting a char.
That is replace you calls to str1<<(char)DeC; with outted.append(1, (char)DeC) and remove your use of the string stream
What is DeC? The phrase "ascii list" makes me suspect it's a 'C' string, in which case you are calling isAlpha() on the pointer not on the value in the string.
edit: If for example you have
char DeC[40];
// read in a string form somewhere
// DeC is a pointer to some memory it has a value of a 32 or 64bit number
if ( isAlpha(DeC) {
// what you might have meant is
if ( isAlpha(*DeC) { // the character value at the current position in DeC