Writing an atoi to convert string to integer - c++

I am writing an atoi to convert string to integer. Here is my code of atoi()function
int atoi(string str) {
int num=0;
int sign=1;
int len=str.size();
int i=0;
if(str[i]==' '&& i<len) i++;
if(str[i]=='+') i++;
if(str[i]=='-') {i++;sign=-1;}
for(;i<len;i++){
if(str[i]==' ') break;
if(str[i]<'0' || str[i]>'9') break;
if(INT_MAX/10<num || INT_MAX/10==num && INT_MAX%10<(str[i]-'0'))
{ return sign==-1 ?INT_MIN:INT_MAX;
break;
}
num=num*10+str[i]-'0';
}
return num*sign;
}
However, when input '1', output is 0, Why is that please?

well the code is kind of buggy:
this if(str[i]<'0' || str[i]>'9') break; won't get you very far; if you input 12aaa you want your method to return some error code or nothing, not the integer part of the string.
I don't even know what this is supposed to be....
if(INT_MAX/10<num || INT_MAX/10==num && INT_MAX%10<(str[i]-'0'))
{ return sign==-1 ?INT_MIN:INT_MAX;
break;
}
Get rid of the last if statement I highlighted, correct the first one so that the code does not try to convert anything other than valid integer strings, and the code should work.

Related

String & is not reflecting changes made But String does....while passing arguments?

Question - Given a string a '0', '1' and '?'. Generate all possible strings where you can replace '?' with '0' or '1' ?
For eg - Input - "0??"
Output - "000", "001", "010", "011".
I have written a simple program for it -
void gen(string& str, int index)
{
int i;
if(str.length() == index)
{
cout << str << endl;
return;
}
else
{
for(i=index; str[i]!='\0' && str[i]!='?';i++);
if(str[i] == '?')
{
str[i] ='0';
gen(str,i+1);
str[i] ='1';
gen(str,i+1);
}
}
return;
}
int main()
{
string s ="0??";
gen(s, 0);
return 0;
}
It is not working correctly....
BUT IF YOU REPLACE THE ARGUMENT IN void gen(String &, int) to
void gen(String, int)....
THEN IT WILL WORK CORRECTLY..
Can Anyone explain me please....
When you pass the string by reference, there is a single string that is operated on by all of the recursive calls to gen() - instead of each call to gen() working on its own local copy. Each recursive call to gen() modifies the (shared) string, removing all the '?' characters; when that call returns, there are no more '?' characters left to process so it simply terminates.
when you pass the string by value, each invocation of the gen() function gets its own local copy of the string; Any changes it makes to that string are thrown away and forgotten when the function returns to the previous level. In this case your logic is correct.
(There was also a bug which caused it to crash on my Windows machine until I fixed it: std::string is not null-terminated, so rather than checking for std[i] == '\0' you should do something like i < str.length().)
reference will maintain the value changed in the function call
after set str[1] ='0';
sub call: gen(str,2); will output combination: 000 001
reset str[1] ='1';
str is still 011
gen(str,i+1); output nothing
hope this piece of code can help
#include <string>
#include <iostream>
#include <stdio.h>
using namespace std;
void gen(string& str, int index)
{
int i;
if(str.length() == index)
{
cout << str << endl;
return;
}
else
{
for(i=index; str[i]!='\0' && str[i]!='?';i++);
if(str[i] == '?')
{
printf("before set pos %d to 0: %s\n",i,str.c_str());
str[i] ='0';
printf("after set pos %d to 0: %s\n",i,str.c_str());
gen(str,i+1);
printf("before set pos %d to 1: %s\n",i,str.c_str());
str[i] ='1';
printf("after set pos %d to 1: %s\n",i,str.c_str());
gen(str,i+1);
}
}
return;
}
int main()
{
string s ="0??";
gen(s, 0);
return 0;
}
it outputs:
One simple solution will be:
As each '?' should be replaced with 0 and 1, we can see that there will be '2 ** (number of ?)' such possible replacement in the string. Eg., if we have three '?' in the string there will be 8 such possible replacement and if we consider their numeric value, they will be 0,1,2...,7 and binary representation of which will be 000,001,002,....,111. Basically we should take the the numeric values and replace the '?'s with the bits from the numeric values.

Printing null character when input is odd character amount

I've been toying with this c program for a while, and I can't seem to figure out what I'm missing.
In the very bottom of my code, I have a function that replaces every other word with a "-".
My problem is that when I enter an odd numbered word, such as "Cat", "dog", "hamburger", it will place a "-" in what I think is the null character position, though I have not been able to debunk it.
Thank you for your help!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void replace(char w[]);
int main( )
{
char w[100], x[100], y[100];
int z = 0;
printf("Player 1, please enter the secret word: ");
fgets(x,100,stdin);
// system("clear");
while( strcmp(x,y) != 0 )
{
strcpy(w,x);
// printf("\nLength of String : %d", strlen(w)-1);
replace(w);
printf("Player 2, the word is %s\n",w);
printf("Player 2, please guess the word: ");
fgets(y,100,stdin);
z++;
if( strcmp(x,y) != 0 )
{
printf("Wrong. Try again.\n");
}
else
{
//system("clear");
printf("Correct!\n");
printf("It took you %d attempt(s).\n",z);
switch (z)
{
case 1 :
case 2 :
printf("A. Awesome work!");
{break;}
case 3 :
case 4 :
printf("B. Best, that was!");
{break;}
case 5 :
case 6 :
printf("C. Concentrate next time!");
{break;}
case 7 :
printf("D. Don't quit your day job.");
{break;}
default :
printf("F. Failure.");
{break;}
}
}
}
getch();
}
void replace(char w[])
{
int a;
a = 0;
while (w[a] != '\0')
{
if (a % 2 != 0)
{
w[a] = '-';
a++;
}
if (w[a] != '\0')
{
a++;
}
else
{
break;
}
}
}
From the fgets manual;
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte (\0) is stored after the last character in the buffer.
The newline entered is what you're replacing.
You can implement like this...
int a;
int len;
a = 0;
len = strlen(w);
if(len%2 == 0)
len = len-1;
while (len!=a)
{
if (a % 2 != 0)
{
w[a] = '-';
a++;
}
if (w[a] != '\0')
{
a++;
}
else
{
break;
}
}
I think replacing fgets with just gets will work:
Try:
//fgets(x,100,stdin);
gets(x);
and
//fgets(y,100,stdin);
gets(y);
That will be enough I think.
The problem is caused by the additional '\n' character in the char array passed to the replace function.
For instance, when the input is "Cat", the passed char[] w contains {'C', 'a', 't', '\n', '\0'};
The additional '\n' also gets replaced with "-" character.
The following will solve this problem.
while (w[a] != '\0')
{
if (w[a] != '\0' && w[a] != '\n')
{
if (a % 2 != 0)
{
w[a] = '-';
}
a++;
}
else
{
break;
}
}
As a bit of an aside, can I suggest structuring your replace() code differently
void replace(char charw[])
{
int length=strlen(charw);
int i;
for (i=0;i<length;i++)
{
if (i%2==1) /*yes, i%2 would also work, but lets not get too clever*/
{charw[i]='-';}
}
}
This is far more readable. Breaking in the middle of a loop...not so much.

If statement is not working even statement is true

My text file contain
Wew213
Wew214
Wew215
and my input in program is
Wew213
but it show me output
"Not Matched"
Actually what i am doing is i want to enter the input and if input match the number in a text file it should run the output by if statement otherwise else statement
here is my program
char file_data[10];
std::ifstream file_read ("D:\\myfile.txt");
cout<<"Enter the number to search"<<endl;
char val[10];
cin>>val;
while(!file_read.eof())
{
file_read>>file_data;
cout<<file_data<<endl;
}
if (val == file_data)
{
cout<<"Matched"<<endl;
}
else
{
cout<<"Not Matched"<<endl;
}
}
you are comparing the pointer value, which is different
you need to use strcmp to compare c string. or use std::string
if (strcmp(val, file_data) == 0)
{
cout<<"Matched"<<endl;
}
else
{
cout<<"Not Matched"<<endl;
}
or
if (std::string(val) == std::string(file_data))
{
cout<<"Matched"<<endl;
}
else
{
cout<<"Not Matched"<<endl;
}
The == test compares the addresses val and file_data. Instead of ==, to compare the contents of the character arrays use the function strcmp().
The given code,
char file_data[10];
std::ifstream file_read ("D:\\myfile.txt");
cout<<"Enter the number to search"<<endl;
char val[10];
cin>>val;
while(!file_read.eof())
{
file_read>>file_data;
cout<<file_data<<endl;
}
if (val == file_data)
{
cout<<"Matched"<<endl;
}
else
{
cout<<"Not Matched"<<endl;
}
}
looks like this after running it through AStyle:
char file_data[10];
std::ifstream file_read ("D:\\myfile.txt");
cout<<"Enter the number to search"<<endl;
char val[10];
cin>>val;
while(!file_read.eof())
{
file_read>>file_data;
cout<<file_data<<endl;
}
if (val == file_data)
{
cout<<"Matched"<<endl;
}
else
{
cout<<"Not Matched"<<endl;
}
}
So, since the checking is done after the loop, checking only the last item read by the loop, even if you got the string comparison itself correct your program would not work.
The comparison doesn't work because, as others (rushing in) have already noted, you're comparing pointers, not strings.
To compare strings, use std::string instead of character arrays.
Minor correction: instead of
while(!file_read.eof())
write
while(!file_read.fail())
or just
while(file_read)
which calls fail for you (negating the result).
But doing this you would also have to check for success/failure of the input operation.
And the common idiom is to do that directly:
while( file_read>>file_data )
The == operator will simply compare the address. You will need to use strcmp function.
character arrays have no the comparision operator. So instead of comparing arrays theirself you are comparing addresses of first elements of the arrays.

Taking string as input character by charcter and giving output on pressing enter

I want to write a program in C or C++ which takes a string as a input character by character and gives output when enter key is pressed. I have to take the input character by character.
while (1)
{
scanf("%c",&a); //cin>>a;
if(a=='\n')
break;
//do operation on the character
}
//give output
something like this but I am not able to do it.
IIUC, you're looking for the getchar function:
while (1)
{
char c = (char)getchar();
if(c=='\n')
break;
//do operation on the character
}
//give output
Ideally your code should work properly.
Since a scanf reads a character and stores it.
What is the error/output you are getting?
Also try comparing (a==10)
10 is the ascii value of '\n'
Try this:
int main()
{
char str[100],c;
int i =0;
while((c=getc(stdin)) != '\n')
{
str[i] = c;
i++;
}
str[i] = '\0';
printf("%s",str);
return 0;
}
Here is one way:
char ch;
while(1)
{
if((ch=getchar())=='\n')
break;
}// its working fine
And another way:
char ch;
while(1)
{
scanf("%c",&ch);
if((ch=='\n'))
break;
}

Reading single char's into variables from file c++

I am messing around with file input/output and I am trying to make a encoding/decoding program. I need help reading the encoded chars from the file back into the program to be decoded. (this is not an assignment, as I am only going into 9th grade next year, I am trying to do this because it seemed challenging.)
Here's my code:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>
#include <cstdlib>
/*
* OUT: categorize words into char's, assign a symbol/number to each char, output number
* combonation to file.
IN: load file, decode file, read decoded version. */
using namespace std;
void Encode(){
char message[100];
char ENCODED[100];
cout<<"input new content:\n>";
cin.getline(message, 99);
cin.ignore();
cout<<"encoding...\n";
for (int i=0; i<100; ++i){
if (message[i]=='a') ENCODED[i]='1';
else if (message[i]=='b') ENCODED[i]='$';
else if (message[i]=='c') ENCODED[i]='!';
else if (message[i]=='d') ENCODED[i]='*';
else if (message[i]=='e') ENCODED[i]='2';
else if (message[i]=='f') ENCODED[i]='&';
else if (message[i]=='g') ENCODED[i]='^';
else if (message[i]=='h') ENCODED[i]='%';
else if (message[i]=='i') ENCODED[i]='3';
else if (message[i]=='j') ENCODED[i]='=';
else if (message[i]=='k') ENCODED[i]='_';
else if (message[i]=='l') ENCODED[i]='-';
else if (message[i]=='m') ENCODED[i]='2';
else if (message[i]=='n') ENCODED[i]='9';
else if (message[i]=='o') ENCODED[i]='4';
else if (message[i]=='p') ENCODED[i]='|';
else if (message[i]=='q') ENCODED[i]='/';
else if (message[i]=='r') ENCODED[i]='>';
else if (message[i]=='s') ENCODED[i]='?';
else if (message[i]=='t') ENCODED[i]='}';
else if (message[i]=='u') ENCODED[i]='5';
else if (message[i]=='v') ENCODED[i]=',';
else if (message[i]=='w') ENCODED[i]='.';
else if (message[i]=='x') ENCODED[i]=';';
else if (message[i]=='y') ENCODED[i]=')';
else if (message[i]=='z') ENCODED[i]='#';
else if (message[i]==' ') ENCODED[i]='#';
else if (message[i] =='\0') {ENCODED[i] = '\}'; break;}
else ENCODED[i]=' ';
}
cout<<"done encoding.\n";
cout<<"exporting file...\n";
ofstream OUTfile ("encoded.txt");
OUTfile<<ENCODED;
cout<<"file exported to parent directory.\n";
cin.get();
}
void Decode(){ //this is where I run into problems!!
string encoded[100]
char DECODED[100]
ifstream INfile ("encoded.txt");
cout<<"Decoding...\n";
INfile>>encoded;
for (i=0; i<100; ++i){
if (encoded[i]=='1') DECODED[i]='a';
else if (encoded[i]=='$') DECODED[i]='b';
else if (encoded[i]=='!') DECODED[i]='c';
else if (encoded[i]=='*') DECODED[i]='d';
else if (encoded[i]=='2') DECODED[i]='e';
else if (encoded[i]=='&') DECODED[i]='f';
else if (encoded[i]=='^') DECODED[i]='g';
else if (encoded[i]=='%') DECODED[i]='h';
else if (encoded[i]=='3') DECODED[i]='i';
else if (encoded[i]=='=') DECODED[i]='j';
else if (encoded[i]=='_') DECODED[i]='k';
else if (encoded[i]=='-') DECODED[i]='l';
else if (encoded[i]=='2') DECODED[i]='m';
else if (encoded[i]=='9') DECODED[i]='n';
else if (encoded[i]=='4') DECODED[i]='o';
else if (encoded[i]=='|') DECODED[i]='p';
else if (encoded[i]=='/') DECODED[i]='q';
else if (encoded[i]=='>') DECODED[i]='r';
else if (encoded[i]=='?') DECODED[i]='s';
else if (encoded[i]=='}') DECODED[i]='t';
else if (encoded[i]=='5') DECODED[i]='u';
else if (encoded[i]==',') DECODED[i]='v';
else if (encoded[i]=='.') DECODED[i]='w';
else if (encoded[i]==';') DECODED[i]='x';
else if (encoded[i]==')') DECODED[i]='y';
else if (encoded[i]=='#') DECODED[i]='z';
else if (encoded[i]=='#') DECODED[i]=' ';
else if (encoded[i] =='\0') {DECODED[i] = '\}'; break;}
else DECODED[i]==' ';
}
cout<<"Decoded file content: "<<DECODED;
cin.get();
}
int main(){
string choice;
cout<<"Encode new message or decode previous file?\n> ";
cin>>choice;
cin.ignore();
if (choice=="encode") Encode();
if (choice=="decode") Decode();
return 0;
}
As you can see, I have no idea what I am doing when it comes to the Decode function.
ANY help would be appreciated! Thank you!
EDIT: I updated the code with the suggestions provided, but When the compiler gets to the line " INfile>>encoded;" it says there is no match for operator ">>" in "INfile>>encoded"...
Problems:
Compilation failed (g++-4.5.1) with no suitable overload of the ifstream constructor found, needs name.c_str().
ifstream INfile (name);
There are semicolons missing on the next two declarations
char encoded[100]
char DECODED[100]
The loop counter i is undeclared (for(int i = 0; ...)
for (i=0; i<100; ++i){
if (encoded[i]=='1') DECODED[i]='a';
From here on, you're comparing DECODED[i] to character constants, not assigning them. Replace all these DECODED[i]== by DECODED[i] =.
else if (encoded[i]=='$') DECODED[i]=='b';
else if (encoded[i]=='!') DECODED[i]=='c';
else if (encoded[i]=='*') DECODED[i]=='d';
One further problem is that you encode and decode 100 characters, no matter whether the actual message is shorter. In both, Decode() and Encode(), add a check for the end of the string
if (array[i] =='\0') {
other_array[i] = '\}';
break;
}
to end the conversion.
I believe the problem here is that you do not understand the difference between char and string. A char is a letter or symbol, like 'a' 'b' 'c' '1' '0' '^' ( etc. But a string - it as a sequence of chars, like "abc" "123" "*&^" etc. In C/C++ to specify a char we use single quote, like 'a'. A value inside single quotes can only have one letter inside. To specify a string we use double quotes, like a mentioned before. A value inside double quotes may have as many characters as you want.
Since this is an exercise for yourself, may I suggest that you create a mapping to avoid those crazy if-statements (and make it easier to modify your encodings later):
// Warning: always address these with ints or unsigned char, not char
// if you expect extended ASCII characters
static unsigned char encode_map[256] = {0};
static unsigned char decode_map[256] = {0};
void InitEncodingMap()
{
encode_map['a'] = '1';
encode_map['b'] = '$';
encode_map['c'] = '!';
encode_map['d'] = '1';
// etc...
encode_map['z'] = '#';
encode_map[' '] = '#';
// Create the reverse map
for( int i = 0; i < 256; i++ ) {
unsigned char encoded = encode_map[i];
if( decode_map[encoded] != 0 ) {
printf("Collision for mapping %c -> %c\n", (char)i, encoded );
} else {
decode_map[encode_map[i]] = (unsigned char)i;
}
}
}
Now, try rewriting your Encode and Decode functions to use these maps.