I'm working on program that counts letters in a piece of text, I can't seem to get it to work. Could someone please point out what I'm doing wrong.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string inputxt;
cout << "enter txt:\n";
getline(cin, inputxt);
char charcheck[ ]={'a', 'b', 'c', 'd'};
int charsize=sizeof(charcheck)/sizeof(char);
int count[charsize];
cout << charsize;
for (int i=0; i==inputxt.length(); i++){
for(int a=0; a==charsize; a++){
if (inputxt[i]==charcheck[a])
++count[a];
}
}
for (int b=0; b==charsize; b++){
cout << "number of " << charcheck[charsize] << ": " << count[charsize];
cout << endl;
}
return 0;
}
Please note I have not put in all the characters to check the text against. Thanks.
for (int i=0; i==inputxt.length(); i++){
The for construct takes 3 parameters:
initialization
continuation condition (and not termination condition like you did). read it as a while ...
loop action (aka. afterthought)
In other words, for (INIT; CONTINUATION; AFTERTHOUGHT) { BODY } is directly translated as:
INIT;
while (CONTINUATION) { BODY; AFTERTHOUGHT; }
Reverse your middle condition, it should be i!=inputxt.length(). The same applies to every other for loops.
In your for loops, you're using == instead of <. For example:
for (int i=0; i==inputxt.length(); i++)
should be:
for (int i=0; i < inputxt.length(); i++)
Related
I had coaching today and we wrote this little code. What it does is obvious so I wont explain in details. After I run it and type something in, it does not print anything, and does not terminate either. If I switch chars for ints, it works fine. What is wrong with this code?
#include<iostream>
#include<string>
using namespace std;
int main()
{
cout << "wpisz zdanie: ";
string zdanie;
getline(cin, zdanie);
int tab[256];
for(char i=0; i<=255; i++)
{
tab[i] = 0;
}
for(int i=0; i<=zdanie.size()-1; i++)
{
tab[zdanie[i]]++;
}
for(char i=0; i<=255; i++)
{
if(i>='0' && i<='Z')
{
cout << (char)i << " -> " << tab[i] << endl;
}
}
return 0;
}
The issue here is that the char data type has values from -128 to 127, so no matter how much you increment them, they will never reach 255. They will just loop back to -128 after going over 127. You can try using unsigned char or int.
Can someone please let me know why one can't take an input in arrays of pointer to strings using input stream as in the following code:
char *names[5];
for(int i=0; i<5; i++)
{
cout<<"enter name "<<i+1;
cin>>names[i];
}
The variable "names" is an undefined array of char pointers. That's your first problem. The pointers are undefined and have no memory allocated for them.
In your original code example there are five char pointers with undefined values. This is why the program would crash, because it's trying to access memory of the invalid address in the pointers.
Another problem is that there is no memory allocated to hold the array of chars coming in from stdin.
You could do something like this to get your original example working without crash:
#include <iostream>
#include <string.h>
using namespace std;
int main(int argc, char** argv)
{
char names[5][128];
memset(names, 0, sizeof(names));
for (int i = 0 ; i < 5 ; i++ )
{
cout << "enter name " << i+1 << ": ";
cin >> names[i];
}
for (int i = 0 ; i < 5 ; i++ )
{
cout << names[i] << "\n";
}
}
This allocates an array of 5 128 character strings. It also clears the arrays with the memset() as well.
Since this is C++ it would seem to make more sense to do it C++ style.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
const int NUM_NAMES = 5;
int main(int argc, char** argv)
{
vector<string> names;
names.resize(NUM_NAMES);
for (int i = 0 ; i < NUM_NAMES ; i++ )
{
cout << "enter name " << i+1 << ": ";
cin >> names[i];
}
for (int i = 0 ; i < NUM_NAMES ; i++ )
{
cout << names[i] << "\n";
}
}
Disclaimer:
using char* for reading from std::cin is generally a bad idea and I suggest you learn how to use std::string in future.
Also this question would have been better suited for codereview.SE but I'll ignore that for now.
Here is an example of doing what you want to do, but I strongly insist you avoid doing it in any real code.
char * names[5];
// Allocate names
for (int i = 0; i < 5; i++)
{
// Use 256 characters as a buffer
// any names longer than that might cause errors
names[i] = new char[256];
}
// Do IO
for (int i = 0; i<5; i++)
{
// Append std::endl
std::cout << "enter name " << i + 1 << std::endl;
// This isn't very robust since the user can give anything as a name,
// and they can't use spaces because of how cin works in this example.
std::cin >> names[i];
}
// Use names
for (int i = 0; i < 5; i++)
{
// Printing names is just an example
// you could write the names to somewhere more important
// you could copy them to a smaller location to use less memory
std::cout << names[i] << std::endl;
}
// Dispose of names when done
for (int i = 0; i < 5; i++)
{
// Check pointer isn't null
if (names[i] != nullptr)
{
// Never forget to delete
delete names[i];
}
}
Here is the code::
#include <iostream>
using namespace std;
const int MAX = 4;
int main ()
{
char key[20];
char *names[MAX];
for (int i=0; i<MAX; i++)
{
cout << " entr keys\n";
cin >> key;
names[i]=key;
cout<< names[i];
}
for(int i=0; i<MAX;i++)
{
cout << names[i];
}
return 0;
}
When I enter the keys and print them in the 1st for loop they show the right value, but when I print names[i] in the 2nd for loop it keeps showing the last key entered again and again.
Please tell me: where am I going wrong?
When you run names[i]=key; you don't really copy key's string value to names[i].
It just makes name[i] point to where key is (since both name[i] & key are pointers).
so all in all you're overwriting key several times, and making all of names pointers point to key.
You need to copy those strings either by working with std::string instead of char* or by using strcpy. I'd recommend on working with std::string.
Using std::string your code should look like this:
#include <iostream>
#include <string>
using namespace std;
const int MAX = 4;
int main ()
{
string names[4];
for (int i = 0; i < MAX; i++)
{
cout << "entr keys" << endl;
cin >> names[i];
cout << names[i];
}
for(int i=0; i<4;i++)
{
cout << names[i];
}
return 0;
}
Every time you execute the lines
cout << " entr keys\n";
cin >> key;
you're inserting a null-terminated string into key, e.g. "hello\0".
Afterwards you copy key's address and store it into a cell of the names pointers array:
names[i]=key; // Now I point to 'key'
cout<< names[i];
then the cycle starts again. Anyway from the second time on you're inserting null-terminated strings into key and thus overwriting the previous contents. The second time if you had entered "hi\0" the contents of the key array would become
['h', 'i', '\0', 'l', 'l', 'o', '\0']
anyway you're going to only print the first string since the null terminator will prevent the other content from being displayed.
When the program ends you're going to have four pointers to the same key array and that array will only contain the last element inserted which overwrote the previous ones.
In order to solve you can make your array a bidimensional one (or use a string array):
const int MAX = 4;
int main ()
{
char key[4][20]; // <- Now this has two indices
char *names[4];
for (int i = 0; i < MAX; i++)
{
cout << " entr keys\n";
cin >> key[i];
names[i]=key[i];
cout<< names[i];
}
for(int i=0; i<4;i++)
{
cout << names[i];
}
return 0;
}
Live Example
Corrected program:
#include <iostream>
using namespace std;
#include <cstring>
const int MAX = 4;
int main ()
{
char key[20];
char *names[MAX];
for (int i = 0; i < MAX; i++)
{
cout << " entr keys\n";
cin >> key;
names[i] = new char[strlen(key) + 1];//names[i]=key;
strcpy(names[i], key);
cout<< names[i];
}
for(int i=0; i<MAX;i++)
{
cout << names[i];
}
for(int i=0; i<MAX;i++)
{
delete [] names[i];
}
return 0;
}
You need to allocate space for each names[i] and when done, deallocate
also, changed the hardcoded 4 to MAX
I'm trying to write a sort to sort an array of strings in ascending order I have the function as:
void mySort(string list[], int size) {
for (int i=0; i<size; i++){
for (int j=0; j < size-i; j++){
if (strcmp(list[j].c_str(),list[j+1].c_str())< 0);{
std::swap(list[j], list[j + 1]);
}
}
}
}
and then the function that uses the sort:
void q0run(question q){
std::string input = q.programInput; //Place the data file in a variable
//cout << input << endl; //Test to make sure data file stored correctly - works
std::ifstream inputFile (input.c_str()); //Open File
if(inputFile.good()){ //Make sure file is open before trying to work with it
//Begin Working with information
cout << "In File: \t" << input << endl;
int number_of_lines = 0;
std::string line;
while (std::getline(inputFile, line)){
++number_of_lines;
}
std::cout << "Number of lines in text file: " << number_of_lines << endl;
std::string dataStorage[number_of_lines];
inputFile.clear();
inputFile.seekg(0);
for(int loop=0;loop<number_of_lines;loop++){
getline(inputFile,dataStorage[loop]);
}
mySort(dataStorage,number_of_lines);
for(int loop=0;loop<number_of_lines;loop++){
cout << dataStorage[loop] << endl;
}
inputFile.close();
}else{
cout << "Could not open file!!!" << endl;
}
}
When I run the program though it segfaults at the sort. Not sure what I'm doing wrong:
In File: data01a.txt
Number of lines in text file: 253
Segmentation fault (core dumped)
The array to be sorted is being populated, I can run a loop on it and print it all out unsorted, any ideas? An easier sorting method will be fine too! Thanks!
if (strcmp(list[j].c_str(),list[j+1].c_str())< 0);{
Oops!
There's an extra ; so the swap will always occur;
Your inner loop needs one fewer iterations, otherwise j+1 jumps off the end;
And are all those C-string conversions really necessary?
std::string::compare would do the job...
The actual bug in your code was answered in a comment.
Your "j+1" index can be out of bounds and in the first iteration it is. You therefore need to loop j up to size-i-1 or iterate i from 1 onward, thus..
for (int i=1; i<size; i++)
I assume this is some kind of exercise as the correct way to sort is simply to use std::sort.
You have also been offered alternative ways to compare two strings, the simplest of which is just its overloaded operator<, thus
if( list[j] < list[j+1] )
You have an out of bounds access which may be the cause
for (int i=0; i<size; i++){
for (int j=0; j < size-i; j++){
if (strcmp(list[j].c_str(),list[j+1].c_str())< 0){
std::swap(list[j], list[j + 1]);
}
On the first iteration you have
i=0; j=size-1 =>strcmp(list[size-1].c_str(),list[size])
change the stop condition in the first loop:
for (int i=0; i<size-1; i++){
for (int j=0; j < size-i; j++){
if (strcmp(list[j].c_str(),list[j+1].c_str())< 0){
std::swap(list[j], list[j + 1]);
}
hope this helps.
This code does what you want in C++11:
#include <algorithm>
#include <iostream>
#include <array>
#include <string>
using namespace std;
int main()
{
string s1 = "hello";
string s2 = "world!";
string s3 = "peanut";
string s4 = "butter";
array<string,4> ar = {s1,s2,s3,s4};
sort(ar.begin(),ar.end());
for(auto elem : ar)
cout << elem << endl;
return 0;
}
My question is simple. I have a 'for' statement in a c++ program and when I compile ignores my cout.
I am using xcode, compiling with xcode and here is my code:
#include <iostream>
using namespace std;
int main ()
{
cout << this prints" << endl;
for(int i=0; i>10; i++)
{
cout << "this doesn't" << endl;
}
return 0;
}
What is the problem?
for(int i=0; i>10; i++)
You initialize i to 0 then only enter the body of the loop if i is greater than 10.
The loop loops as long as the condition i > 10 is true, not until the condition i > 10 is true. This is how all the loops in C++ work: for, while, and do/while.
Your loop condition is backwards. You want it to be i < 10.
You have got the condition for loop incorrect. This should work. Check below:
#include <iostream>
using namespace std;
int main ()
{
cout << "this prints" << endl;
for(int i=0; i<= 10; i++) // ------> Check the change in condition here
{
cout << "this doesn't" << endl;
}
return 0;
}