C6001: using unititialized memory "str[i]" - c++

The program works fine, although the fist printed number is always "3452816845". I have tried initializing "str[i]" by adding curly brackets when defining the array, or by giving it NULL value, but then the first printed number is always "zero", and only then it prints what I entered. Please take a look below:
#include <iostream>
using namespace std;
int main() {
unsigned* str = new unsigned[1000];
int cnt = 0;
char ch;
int a;
cout << "Please enter text: ";
do {
cin.get(ch);
if (ch <=57 && ch >=48) {
int a = ch - '0';
cnt++;
str[cnt] = a;
}
} while (ch != '\n');
cout << "The entered numbers are: ";
for (int i = 0; i <= cnt; i++) {
cout << str[i] << " "; // here is where the error appears
}
delete[] str;
return 0;
}

Do not using namespace std;. Especially not in headers, but try to not use it in plain .cpp files either. It's more convenient to debug code that unambiguously tells you which namespace an identifier came from right where that identifier is being used.
unsigned* str = new unsigned[1000];
Since the advent of C++11, "naked" memory allocation like that is frowned upon, and is definitely not necessary here.
You could just use a static array (unsigned str[1000];).
You could use smart pointers (auto str = std::make_unique<char[]>(1000);).
Best choice, use C++ containers, like <vector>, <string>, or (if overhead really bothers you) <array>.
if (ch <=57 && ch >=48) {
int a = ch - '0';
Do not use "magic numbers" in your code. If you want to know if the character entered is a digit, use isdigit, which is more expressive and works even for non-ASCII encodings that might have their digits at a different location in the code table.
int a = ch - '0';
This isn't wrong, as the standard guarantees this to work for digits. Note that similar arithmetic on characters (the infamous ... - 'a') is frowned upon though, and will break as soon as you leave the realm of strict ASCII-7 encoding.
cnt++;
str[cnt] = a;
C/C++ start counting at zero. You just left the first item in the array uninitialized. The beauty of the post-increment is that you can do it right there where you use the index, i.e. str[cnt++] = a;.
for (int i = 0; i <= cnt; i++)
cout << str[i] << " "; // here is where the error appears
}
Very C, and also wrong. You didn't initialize str[0], so the first round through that loop accesses uninitialized memory. If you had initialized str[0] (by incrementing cnt only after using it as an index), i <= cnt would go one item beyond what you wrote into str[], again accessing uninitialized memory. A loop should run from 0 to < cnt (not <=).
If you took my earlier advice to use <vector> or <string>, there's a much better way to loop through the items stored in it, the range-for.
#include <iostream>
#include <vector>
int main()
{
char ch;
std::vector< int > digits;
std::cout << "Please enter text: ";
do
{
std::cin.get( ch );
if ( std::isdigit( ch ) )
{
digits.push_back( ch - '0' );
}
} while (ch != '\n');
std::cout << "The entered numbers are: ";
for ( auto & i : digits )
{
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}

You never initialize str[0], but you output it.

The problem is here:
...
if (ch <=57 && ch >=48) {
int a = ch - '0';
cnt++;
str[cnt] = a;
}
...
You are incrementing cnt too early, leaving str[0] uninitialized. You should do:
if (ch <=57 && ch >=48) {
int a = ch - '0';
str[cnt++] = a;
}
Also you do have a problem in your for loop; You should start from 0 till the last initialized element in the string which is at index cnt - 1. It should be like this:
for (int i = 0; i < cnt; i++) {
cout << str[i] << " ";
}
or
for (int i = 0; i <= cnt - 1; i++) {
cout << str[i] << " ";
}

Related

I can't figure out why my while loop is not giving the expected result ):

I can't figure out what I'm doing wrong. I am new to c++ and am practicing. I found code that writes two letter combinations with nested while loops and adds .com at the end. That code worked fine. In order to practice I wanted it to output a third combination but for some reason everytime I add the a third while loop the one in the middle only outputs {. Any help is greatly appreciated! Thank you!!!
#include <iostream>
using namespace std;
int main() {
char letter1;
char letter2;
char letter3;
cout << "Three-letter domain names:" << endl;
letter1 = 'a';
while (letter1 <= 'z') {
letter2 = 'a';
while (letter2 <= 'z') {
letter3 = 'a';
++letter2;
}
while (letter3 <= 'z') {
cout << letter1 << letter2 << letter3 << ".com" << endl;
++letter3;
}
++letter1;
}
return 0;
}
Your third loop needs to be nested inside your second loop.
But there is an easier way which has the added bonus that it's also portable C++ (your assumption that the lower case letters are contiguous is the issue). Essentially this is a single integral counter converted to a base 26 radix:
#include <iostream>
int main() {
constexpr char alphabet[] = "abcedfghijklmnopqrstuvwxyz";
constexpr std::size_t radix = sizeof(alphabet) - 1;
for (std::size_t i = 0; i < radix * radix * radix; ++i){
std::cout
<< alphabet[i / radix / radix]
<< alphabet[(i / radix) % radix]
<< alphabet[i % radix]
<< ".com\n"
;
}
}
The third loop shall be a nested loop of the second while loop. That is there should be three nested loops.
Also as the variables letter1, letter2, and letter3 are not used outside the loops it is better to make them local variables of the loops. That is it is better to substitute the while loops for for loops.
Here is a demonstrative program.
#include <iostream>
int main()
{
std::cout << "Three-letter domain names:" << '\n';
for ( char letter1 = 'a'; letter1 <= 'z'; ++letter1 )
{
for ( char letter2 = 'a'; letter2 <= 'z'; ++letter2 )
{
for ( char letter3 = 'a'; letter3 <= 'z'; ++letter3 )
{
std::cout << letter1 << letter2 << letter3 << ".com" << '\n';
}
}
}
}
Its output is
Three-letter domain names:
aaa.com
aab.com
aac.com
aad.com
aae.com
...
and so on.
Pay attention to that in general it is not necessary that letters follow each other without gaps in the used coding system.

Upon running the i get a pop up windows screen saying "prg.exe has stopped working."

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int main()
{
char str[100];
cout << "Enter a string : ";
gets(str);
cout << "The words containing y in their last place are : ";
cout << "\n";
for(int i = 0; str[i] != '\0'; i++)
{
int j = i + 1;
if((str[i] == 'y') && (str[j] == ' '))
{
int k;
cout << 134;
char stress[50];
int m = 0;
k = i;
for(; (str[k] != ' ') || (k != 0); k--, m++)
{
stress[m] = str[k];
}
stress[m] = '\0';
int g;
for(g = 0; stress[g] != '\0'; g++)
;
char strain[g];
for(int n = 0, q = k - 1; q >= 0; n++, q--)
{
strain[n] = stress[q];
}
strain[g] = '\0';
for(int p = 0; p < g; p++)
{
cout << strain[p];
}
cout << "\n";
cout << 1;
}
cout << 12;
}
return 0;
}
This c++ program is to display the word containing 'y' as its last letter. I used cout<<12 cout<<1 etc.. to know which part of program is working.
Dont get confused by seeing strain and stress. They are just strings.
I am using codeblocks in windows 7
Upon running the program i get a pop up windows screen saying "prg.exe has stopped working."
Please someone tell me why this error is occuring.
I use codeblocks
I will be really grateful.
You might have errors because of using gets() function, because when you are using gets() you need to know the amount of characters you will get. It was officialy removed by 2011 standart, but almost every C implementation uses it. So to avoid that dangerous function you can use:
getline(), which is very easy to use - like that:
getline(cin,str);
fgets(), it is used like gets, but you need to mention how many characters you will read:
fgets(str, num_of_chars, cin);

How do I use cin to get a string instead of hard-coding it?

As a homework exercise we were asked to use strchr to count the amount of times a single letter appears in a string of text. It needs to count upper or lower cases as equal. It was suggested we use some sort of bit operations.
I managed to get a working program.
But i would like to make the program more interactive by allowing me to use a cin to input the string instead of typing the string directly into the source code (Which was asked by the exercise).
Is it possible to do this? Or is it not possible in the way i wrote this code.
#include <iostream>
#include <cstring>
using namespace std;
int main(){
const char *C = "This is a necesarry test, needed for testing.";
char target = 'A';
const char *result = C;
const char *result2;
int count = 0;
int j[26] ={0};
//================================================================================================================================================
for(int i = 0; i <= 51; i++){
if (i == 26){
target = target + 6;
}
result2 = strchr(result, target);
while(result2 != NULL){
if (result2 != NULL){
result2 = strchr(result2+1, target);
if (i <= 25){
j[i] = j[i] +1;
}
if(i > 25){
j[i-26] = j[i-26] +1;
}
cout << target << "\t";
}
}
cout << target << endl;
target++;
}
char top = 'a';
for(int o = 0; o<= 25; o++){
cout << "________________________________\n";
cout << "|\t" << top << "\t|\t" << j[o] << "\t|" << endl;
top++;
}
cout << "________________________________\n";
}
Simply use getline() to get a string of characters from the console. Using getline you can also consider the spaces in the user input.
string input;
getline(cin, input);
Now to use this with the strchr functionn you simply have to convert this into a C Type string which can be done as follows :
input.c_str
This returns a C type string so you can put this as an arguement to the function,
You will need
#include <string>

Read digits from an int and counting them

Alright so I've been looking though Google and on forums for hours and can't seem to understand how to solve this problem.
I need to write a program that first determines if the number entered by the user is a base 5 number (in other words, a number that only has 0s, 1s, 2s, 3s, and 4s in it). Then, I have to count how many 0s, 1s, 2s, etc are in the number and display it to the user.
I've seen people saying I should convert int to a string and then using cin.get().
I noticed that I can't use cin.get() on a string, it needs to be a char.
I can only use a while loop for this assignment, no while... do loops.
Any help is appreciated!!
Here's what I have so far, obviously with all my mistakes in it:
//----------------------------------------------
// Assignment 3
// Question 1
// File name: q1.cpp
// Written by: Shawn Rousseau (ID: 7518455)
// For COMP 218 Section EC / Winter 2015
// Concordia University, Montreal, QC
//-----------------------------------------------
// The purpose of this program is to check if the
// number entered by the user is a base of 5
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
// Declaring variables
int number;
int zeros;
int ones;
int twos;
int threes;
int fours;
bool base5;
// Get data and calculate
cin >> number;
string numberString = to_string(number);
// Determine if the number is a base 5 number
while (cin.get(numberString) == 0 || cin.get(numberString) == 1 ||
cin.get(numberString) == 2 || cin.get(numberString) == 3 ||
cin.get(numberString) == 4)
base5 = true;
// Determine the number of each digits
zeros = 0;
ones = 0;
twos = 0;
threes = 0;
fours = 0;
return 0;
}
Several things you need to beware of:
One way to get a specific character from a std::string is by []. e.g.
std::string myString{"abcdefg"};
char myChar = myString[4]; // myChar == 'e'
cin.get(aString) is not trying to get data from aString. It continues to get data from stdin and store in aString. Once you have get the data and put into the string, you can simply manipulate the string itself.
a short piece of code that will count number of vowel in a string. If you can understand it, there should be no problem doing your work. (Haven't compiled, probably some typos)
std::string inputString;
std::cin >> inputString;
// you said you need a while loop.
// although it is easier to with for loop and iterator...
int i = 0;
int noOfVowels = 0;
while (i < inputString.length()) {
if (inputString[i] == 'a'
|| inputString[i] == 'e'
|| inputString[i] == 'i'
|| inputString[i] == 'o'
|| inputString[i] == 'u' ) {
++noOfVowels;
}
++i;
}
std::cout << "number of vowels : " << noOfVowels << std::endl;
Well you can try this approach. This will solve your needs I guess.
#include <iostream>
#include <string>
#include <sstream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int number=0;
int zeros=0;
int ones=0;
int twos=0;
int threes=0;
int fours=0;
bool valid=true;;
int counter = 0;
cout<<"Enter the number: ";
cin >> number;
stringstream out;
out << number; //int to string
string numberString = out.str();
cout<<"\n\nNumber after string conversion : "<<numberString;
cout<<"\nPrinting this just to show that the conversion was successful\n\n\n";
while (counter < numberString.length())
{
if (numberString[counter] == '0')
zeros++;
else if(numberString[counter] == '1')
ones++;
else if(numberString[counter] == '2')
twos++;
else if(numberString[counter] == '3')
threes++;
else if(numberString[counter] == '4')
fours++;
else
valid=false;
counter++;
}
if(valid==true)
{
cout<<"\nZeros : "<<zeros;
cout<<"\nOnes : "<<ones;
cout<<"\nTwos : "<<twos;
cout<<"\nThrees : "<<threes;
cout<<"\nFours : "<<fours;
}
else
cout<<"\n\nInvalid data...base of 5 rule violated";
_getch();
return 0;
}
If you don't want to use std::string then use characters, first loop over the input from the user until ENTER is pressed.
char ch = 0;
while ((ch = cin.get()) != '\n')
{
...
}
For each character read, check if it is a digit (std::isdigit) and if it is in the range 0..4, if not quit and give some message of not being base 5
have an array of ints to keep track of the frequency of the digits
int freq[5] = {0,0,0,0,0};
after you have checked that the character is valid subtract the ascii value from the digit and use that as index in the array, increment that:
freq[ch - '0']++;
e.g.
char ch;
int freq[5] = {0};
while ((ch = cin.get()) != '\n')
{
cout << ch;
freq[ch-'0']++;
}
for (int i = 0; i < sizeof(freq)/sizeof(freq[0]); ++i)
{
cout << static_cast<char>(48+i) << ":" << freq[i] << endl;
}
Here's a useful function that counts digits:
// D returns the number of times 'd' appears as a digit of n.
// May not work for n = INT_MIN.
int D(int n, int d) {
// Special case if we're counting zeros of 0.
if (n == 0 && d == 0) return 1;
if (n < 0) n = -n;
int r = 0;
while (n) {
if (n % 10 == d) r++;
n /= 10;
}
return r;
}
In your code you can use this naively to solve the problem without any further loops.
if (D(n, 5) + D(n, 6) + D(n, 7) + D(n, 8) + D(n, 9) != 0) {
cout << "the number doesn't consist only of the digits 0..4."
}
cout << "0s: " << D(n, 0) << "\n";
cout << "1s: " << D(n, 1) << "\n";
cout << "2s: " << D(n, 2) << "\n";
cout << "3s: " << D(n, 3) << "\n";
cout << "4s: " << D(n, 4) << "\n";
You could also (or should also) use loops here to reduce the redundancy.

c++ for loop is being skipped

What am I doing wrong with this small program.
I'm just starting to learn c++, and by all mean I can accept this as a moot question. I'm reading through the Prata c++ primer and it gave me a code example which takes a char array and uses strcmp() in a for loop which iterates sequentially through the ASCII code starting with '?' until a test char variable ==s a set value from another char.
Thinking I could outdo the book I tried to create a similar program which takes a char array and using a for loop will take a test char array and iterate through each value of the array until the two variables are equal.
I simplified the program to only take the first of each array in the for loop because I was experiencing a problem where the program seems to simply skip over the for loop and terminate.
Below are first the prata code snippet, followed by my piece of code. Any feedback (even abusive >_<) would be useful.
#include <iostream>
#include <cstring>
int main() {
using namespace std;
char word[5] = "?ate";
for (char ch = ‘a’; strcmp(word, "mate"); ch++) {
cout << word << endl;
word[0] = ch;
}
cout << "After loop ends, word is " << word << endl;
return 0;
}
My code (though maybe poorly done, I can accept that)
#include <iostream>
#include <cstring>
int main() {
using namespace std;
char word[5] = "word";
char test[5] = "????";
int j = 0;
int i = 0;
cout << "word is " << word << "\nTest is " << test << endl;
cout << word[0] << " " << test[0] << endl;
for (char temp = '?'; word[0] == test[0] || temp == 'z'; temp++) {
if ((word[i]) == (test[j])) {
test[j] = temp;
j++;
temp = '?';
}
test[j] = temp++;
cout << test << endl; //Added to see if the for loop runs through once,
//which is does not
}
return 0;
}
Your for loop never starts because your condition, shown here:
word[0] == test[0] || temp == 'z'
will always return false on its first pass. Since temp is initialized to '?' and word[0] (w) does not equal test[0] (?), your loop will never start.
Also, you've initialized temp to ? so, looking at an ascii chart, you'll see that there's a lot of non-alpha characters between ? and a lower case z.
Furthermore, within the for loop, you increment j (j++) but never touch i. Since you're reading chars from word with i as your index, test would end up being "wwww".
You seem to be confusing yourself so...
Lets break down what you're trying to do:
If you're iterating every character in a string, then checking each letter of the alphabet at that index, you're going to have two loops:
for(;;) {
for(;;) {
}
}
The first (iterating through each index in the string should end when the index reaches the end of the string (strings literals are terminated with a '\0'):
for(int i = 0; word[i] != '\0' && test[i] != '\0'; i++) {
for(;;) {
}
}
The second will check each letter of the alphabet (char temp = 'a' and temp++) against your given index in both word and test (word[i] != test[i];). If they're not equivalent, it will set the character of test at index i to temp until it finds the right letter. Putting it all together, you end up with this:
for(int i = 0; word[i] != '\0' && test[i] != '\0'; i++) {
for(char temp = 'a'; word[i] != test[i]; temp++) {
test[i] = temp;
}
}
Of course, if you were only going for results and not trying to teach yourself about loops and programming basics, this is all just a very roundabout way of simplay calling:
memcpy(temp, word, strlen(word));