Why is there an extra character at the end of my string?
#include <iostream>
using namespace std;
int main() {
int num;
cin >> num; // Reading input from STDIN
cout << "Input number is " << num << endl; // Writing output to STDOUT
char c1, s2[10];
for (int i=0; i<num; i++)
{
cin >> c1;
if(c1==0){
break;
}
s2[i] = c1;
}
cout <<"output= "<< s2;
}
output example
4
Input number is 4
a l e x
output= alex#
Why is the "#" being added to the end of the string? At first i thought it was a random garbage value but every time I run the program its always the same symbol
cout, when printing a c-string, expects it to zero terminated. Whereas you haven't done so for the array s2.
You can zero initialize the entire array:
char s2[10] = {};
Or just zero terminate the last byte:
int i = 0;
for (i=0; i<num; i++)
{
cin >> c1;
if(c1==0) {
break;
}
s2[i] = c1;
}
s2[i] = '\0';
In any case, you need to be wary of potential buffer overflow (e.g. if num is too large).
Alternatively, you can consider using std::string instead of a fixed length array.
You're reading from a memory location that hasn't been initialized. By using an array of ten characters and only initializing the first four (or whatever else the number is), all other characters stay uninitalized. What data is actually read from an uninitialized location is undefined, meaning it's pretty much up to your compiler that chooses to read the equivalent value of "#" from that location. You can fix that issue by using a memory bit of the appropriate size. For this, you just replace the line
char c1, s2[10];
with
char c1;
char* c2 = new char[num + 1] //num + 1 is necessary to contain a string terminator, see the other answers
this way, you dynamically allocate exactly the size you need.
Don't forget to delete[] c2; afterwards.
You are using a Character sequence well explained here.
By convention, the end of strings represented in character sequences
is signaled by a special character: the null character, whose literal
value can be written as '\0' (backslash, zero).
In this case, the array of 20 elements of type char called foo can be
represented storing the character sequences "Hello" and "Merry Christmas" as:
Notice how after the content of the string itself, a null character
('\0') has been added in order to indicate the end of the sequence.
The panels in gray color represent char elements with undetermined
values.
I offer a c++17 solution with the constructor initialization although I may prefer either a dynamic array or std::string instead of a char.
I also added a simple integer check that always should be used.
Also a few versions of avoiding the use of the whole namespace std for various reasons, mostly to avoid unnecessary errors.
#include <iostream>
#include <limits> //numeric_limits
using std::cout, std::endl, std::cin; //<- explicit declared
int main() {
int num;
while(!(cin >> num)){ //check the Input format for integer the right way
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << "Invalid input. Try again: ";
};
cout << "Input number is " << num << endl;
char c1, s2[num+1]{}; // Initialize with an empty string
for (int i = 0; i < num; i++)
{
cin >> c1;
if (c1 == 0) {
break;
}
s2[i] = c1;
}
cout << "output= " << s2 << endl;
return 0;
}
This happens because s2 is actually not a string and does not have the \0 character, which would mean the end of the string. Therefore, cout prints your string and will continue to move further in memory, byte by byte, interpreting each of them as a character to be output until it encounters the \0 character. In order to fix this, you can initialize s2 with an empty string, so the array will initially be completely filled \0.
#include <iostream>
using namespace std;
int main() {
int num;
cin >> num;
cout << "Input number is " << num << endl;
char c1, s2[10] = ""; // Initialize with an empty string
for (int i = 0; i < num; i++)
{
cin >> c1;
if (c1 == 0) {
break;
}
s2[i] = c1;
}
cout << "output= " << s2;
}
Related
I am trying to convert an input character array, to an int array in c++.
Inputs would be in a format like: 'M 911843 6', where the first value of the char array is a uppercase letter, which I convert to an ASCII value and -55.
Edit: I should also mention I just want to use the iostream library
The last value of the char array can be a letter or number also.
I want to retain the exact number value of any input in the char array, which is why I convert to an ASCII value and -48, which retains the same number, but stored as an int value:
I use the checkdigit() function to check if the char input is a number or not.
The difficulty I am facing is that the input will always have a blank space at i[1] and i[8] (if we count i[0] as the first value) - so I try to give them an int value of 0 (int of a " " is 0)
Upon several debugging attempts, I found that it is after the blank space is given a 0 value, the output in my for loop keeps outputting the wrong values, I suspect it has something to do with the isdigit() function in my for loop.
If the spaces from M 911843 6 were removed, the int output is usually fine, e.g. a char input of
M9118436 will return an int array of [22][9][1][1][8][4][3][6].
The output with spaces: [22][0][-183][-120][37][-118][-59][72][0][-55]
Ideal output: [22][0][9][1][1][8][4][3][0][6]
The code is listed below, any help or advice would be greatly appreciated, thanks!!
#include <iostream>
using namespace std;
int main() {
char a[10];
int z[10];
int i = 0;
int r; //result of the isdigit check (0 or 1)
cout << "in ";
cin >> a;
for (int i = 0; i < 10; i++) {
r = isdigit(a[i]);
if (r == 0) {
if (i==1 || i==8)
z[i] = 0;
else z[i] = int(a[i]) - 55;
}
else {
z[i] = int(a[i]) - 48;
}
}
cout << z[0] << "\n" << z[1] << "\n"<< z[2]<< "\n" << z[3] << "\n"<< z[4] << "\n"<< z[5] << "\n"<< z[6] << "\n"<< z[7]<< "\n" << z[8] << "\n"<< z[9];
return 0;
}
The problem is that cin >> a; does not read sizeof(a) characters, but up to the first space character and will terminate that with a null.
That means that you array will containt 'M', '\0' and 8 uninitialized characters. You must read the characters one at a time with unformatted reads:
for (auto& c : a) {
cin.get(c);
if (!cin) {
cerr << "Incorrect input\n";
return EXIT_FAILURE;
}
}
Just a follow on from Serge's answer which gave me a good understanding of how strings are read - I solved my problem using cin.getline() function.
I explain you the working of this program.
step 1: enter the no. of time you want to run the loop.
step 2: enter two strings s1 and s2.
output : it will give you a string s3 that does not contain any character from string s2.
problem: I am unable to understand the working of for loop, and why the value of hash is 257, and how is loops working.
The code is given below.
#include <iostream>
using namespace std;
#include<string.h>
int main()
{
int t;
cout<<"enter any no. to run the loop"<<endl;
cin>>t;
while(t--)
{
string s1,s2,s3;
int i,j,l1,l2;
cout<<"enter two strings s1 and s2"<<endl;
cin>>s1>>s2;
l1=s1.length( );
l2=s2.length( );
int hash[257];
for(i=0;i<257;i++)
{
hash[i]=0;
}
for(i=0;i<l2;i++)
{
hash[s2[i]]++;
}
for(i=0;i<l1;i++)
{
if(hash[s1[i]]==0)
s3=s3+s1[i];
}
cout<<s3<<endl;
}
return 0;
}
This program figures out which characters in the first string are not contained in the second string.
Example input for the program:
1
abcdefghijklmnopqrstuvwxyz
helloworld
Example output (thanks to #mch for correction)
abcfgijkmnpqstuvxyz
Edit: Note that this is of course case sensitive as characters a and A produce different integer values.
Here is some commentary on the program:
#include <iostream>
using namespace std;
#include <string.h>
int main() {
// Do the whole program as many times as the user says
int t;
cout << "enter any no. to run the loop" << endl;
cin >> t;
while (t--) {
string s1, s2, s3;
int i, j, l1, l2;
// read strings and get their respective lengths
cout << "enter two strings s1 and s2" << endl;
cin >> s1 >> s2;
l1 = s1.length();
l2 = s2.length();
// Array with 257 elements
int hash[257];
// Initialize all elements of array with 0
for (i = 0; i < 257; i++) {
hash[i] = 0;
}
// Count occurrences of characters in second string
// s2[i] is the character at position i in s2
// Increase the value of hash for this character by 1
for (i = 0; i < l2; i++) {
hash[s2[i]]++;
}
// Iterate over s1 characters
// If hash[i] == 0: character i is not contained in s2
// s3 => string of letters in s1 that are not contained in s2
for (i = 0; i < l1; i++) {
if (hash[s1[i]] == 0)
s3 = s3 + s1[i];
}
// output s3
cout << s3 << endl;
}
return 0;
}
The code computes an histogram of occurrences of the letters in s1 and copies the letters of s2 that have zero occurrence.
It can crash for any char type not restricted to the range [0,256] (!)
There's a comment above explaining the for-loops.
int hash[257] could actually be int hash[256] . There are 256 different values that can fit in a char (8 bits).
I have written a code to reverse a string
#include < iostream >
#include < cstring >
using namespace std;
string Reversal(char * s);
int main()
{
char str[25];
cout << "Enter a Name :";
cin.get(str, 25);
cout << "You have entered: " << str;
cout << "\nReversed : " << Reversal(str);
return 0;
}
string Reversal(char * s)
{
int count = strlen(s);
char temp[count];
for (int i = 0; i < count; i++)
{
temp[i] = * (s + (count - 1) - i);
}
return temp;
}
Have referred below link to make cin take whitespaces as input:
How to cin Space in c++?
But the output is showing a few junk characters ? Any suggestion why so?
When you implicitly construct a std::string from temp, the latter is expected to be NUL-terminated, which it isn't.
Change
return temp;
to
return std::string(temp, count);
This uses a different constructor, one that takes an explicit character count and doesn't expect temp to be NUL-terminated.
The last character in the temp array should be null-terminated. Make it 1 longer than the size of your input string. Make the last character the null character ('\0').
string Reversal(char *s)
{
int count=strlen(s);
char temp[count+1]; //make your array 1 more than the length of the input string
for (int i=0;i<count;i++)
{
temp[i]= *(s+(count-1)-i);
}
temp[count] = '\0'; //null-terminate your array so that the program knows when your string ends
return temp;
}
The null character specifies the end of the string. Usually it is a byte with all 0 bits. If you don't specify this as the last character of your temp array, the program will not know when is the end of your array of characters. It will keep including every character until it finds a '\0'.
there's a problem facing me in this question :
"write a c++ console program to accept five
integers values from keyboard in one line separated by spaces . the program then stores the five values in an array using pointer . then print the elements of the array on the screen ."
I tried to make a string variable and accept 5 integers from user then convert it to integer but it doesn't work well because it doesn't take numbers after space .
any help guys ??
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
int main(){
string numbers;
getline(cin, numbers);
int arr[5];
int *ptr;
int values;
stringstream convert(numbers);
convert >> values;
cout << values;
}
It will only take one at a time, you need to add more calls to convert like so:
stringstream convert(numbers);
convert >> values;
cout << values;
convert >> values;
cout << " " << values;
convert >> values;
cout << " " << values;
The C++faq has a good section on this.
Without major modification, if you need to put the number directly into the array using a pointer, you can do this:
int *ptr = arr ;
convert >> *ptr++ ;
convert >> *ptr++;
convert >> *ptr++;
convert >> *ptr++;
convert >> *ptr++;
for( unsigned int i = 0; i < 5; ++i )
{
cout << arr[i] << " " ;
}
cout << std::endl ;
I successfully made it
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
int main(){
int arr[5];
string number;
cout << "Please enter 5 integers separeted with spaces " << endl;
getline(cin, number);
int *ptr = arr ;
stringstream convert(number);
convert >> *ptr++ ;
convert >> *ptr++;
convert >> *ptr++;
convert >> *ptr++;
convert >> *ptr++;
for( int i = 0; i < 5; ++i )
{
cout << arr[i] << " " ;
}
cout << std::endl ;
}
I the numbers variable is string you can search for first non space character using numbers.find_first_not_of(" "); and first space character by numbers.find_first_of(" "); then create a subset using substr(.....) now place the substr in another string variable. Now convert the substring to int. repeat the steps for number of times you need. i.e. place the whole code inside a while loop. Terminate the loop whenever numbers.find_first_of(" ");returns numbers.end()
While using the boolean check for the int num this loop doesn't work. The lines after it go unrecognized. Enter and integer like 60 and it just closes. Did I use isdigit wrong?
int main()
{
int num;
int loop = -1;
while (loop ==-1)
{
cin >> num;
int ctemp = (num-32) * 5 / 9;
int ftemp = num*9/5 + 32;
if (!isdigit(num)) {
exit(0); // if user enters decimals or letters program closes
}
cout << num << "°F = " << ctemp << "°C" << endl;
cout << num << "°C = " << ftemp << "°F" << endl;
if (num == 1) {
cout << "this is a seperate condition";
} else {
continue; //must not end loop
}
loop = -1;
}
return 0;
}
When you call isdigit(num), the num must have the ASCII value of a character (0..255 or EOF).
If it's defined as int num then cin >> num will put the integer value of the number in it, not the ASCII value of the letter.
For example:
int num;
char c;
cin >> num; // input is "0"
cin >> c; // input is "0"
then isdigit(num) is false (because at place 0 of ASCII is not a digit), but isdigit(c) is true (because at place 30 of ASCII there's a digit '0').
isdigit only checks if the specified character is a digit. One character, not two, and not an integer, as num appears to be defined as. You should remove that check entirely since cin already handles the validation for you.
http://www.cplusplus.com/reference/clibrary/cctype/isdigit/
If you're trying to protect yourself from invalid input (outside a range, non-numbers, etc), there are several gotchas to worry about:
// user types "foo" and then "bar" when prompted for input
int num;
std::cin >> num; // nothing is extracted from cin, because "foo" is not a number
std::string str;
std::cint >> str; // extracts "foo" -- not "bar", (the previous extraction failed)
More detail here:
Ignore user input outside of what's to be chosen from