how do I pass a char vector to a char*? I know this problem could easily be solved with a predefined char[] array with a SIZE const, but I want the flexibility of a vector because there will be no predefined size.
using namespace std;
//prototype
void getnumberofwords(char*);
int main() {
//declare the input vector
vector<char> input;
/*here I collect the input from user into the vector, but I am omitting the code here for sake of brevity...*/
getnumberofwords(input);
//here is where an ERROR shows up: there is no suitable conversion from std::vector to char*
return 0;
}
void getnumberofwords(char *str){
int numwords=0;
int lengthofstring = (int)str.size();
//this ERROR says the expression must have a case
//step through characters until null
for (int index=0; index < lengthofstring; index++){
if ( *(str+index) == '\0') {
numwords++;
}
}
}
You can use data() member to get the pointer to the underlying array:
getnumberofwords(input.data());
The most obvious is to pass &your_vector[0]. Be sure to add a NUL to the end of your vector first though.
Alternatively, use std::string instead of std::vector<char>, in which case you can get a NUL-terminated string with the c_str member function.
Edit: I have to wonder, however, why getnmberofwords would be written to accept a char * unless it's some old C code that you just can't get away from using.
Given a typical definition of "word" counting some words that start out in a string can be done something like this:
std::istringstream buffer(your_string);
size_t num_words = std::distance(std::istream_iterator<std::string>(buffer),
std::istream_iterator<std::string>());
You should pass the reference of the vector to the function getnumberofwords.
void getnumberofwords(vector<char>& str){
int numwords=0;
int lengthofstring = str.size();
for (int index=0; index < lengthofstring; index++){
if ( str[index] == '\0') {
numwords++;
}
}
}
There is no method for converting the type from vector to pointer.
here's what I ended up doing which worked:
#include <iostream>
#include <cstring>
#include <string>
#include <iomanip>
using namespace std;
//prototype
void getnumberofwords(char*);
void getavgnumofletters(char*, int);
int main() {
const int SIZE=50;
char str[SIZE];
cout<<"Enter a string:";
cin.getline(str, SIZE);
getnumberofwords(str);
return 0;
}
void getnumberofwords(char *str){
int numwords=0;
int lengthstring=strlen(str);
//step through characters until null
for (int index=0; index < lengthstring; index++){
if (str[index] ==' ') {
numwords++;
}else{
continue;
}
}
numwords+=1;
cout<<"There are "<<numwords<<" in that sentence "<<endl;
getavgnumofletters(str, numwords);
}
void getavgnumofletters(char *str, int numwords) {
int numofletters=0;
double avgnumofletters;
int lengthstring=strlen(str);
//step through characters until null
for (int index=0; index < lengthstring; index++){
if (str[index] != ' ') {
numofletters++;
}else{
continue;
}
}
avgnumofletters = (double)numofletters/numwords;
cout<<"The average number of letters per word is "<<setprecision(1)<<fixed<<avgnumofletters<<endl;
}
/*
Related
I've been trying to bend my head around this problem for a week now, but I can't seem to find anything online and I've given up on trying to solve it on my own.
My assignment is to write a program which will read names from a file and accept new entries from the user, then sort the entires and write them out to the file. The only crux about this is that I have to sort them in a function and use pointers to do so. This code is supposed to be written in C++ aswell, using character arrays.
The code I have right now looks like this. This is a working version, the only problem is that I don't use neither pointers or a function to sort the names.
#include<iostream>
#include<cstdlib>
#include<fstream>
#include<cstring>
bool sorted;
using namespace std;
int main()
{
int i = 0;
int numNames = 0;
ifstream ifs;
ifs.open("namn.txt");
char c[20][20];
if(ifs.is_open())
{
while(!ifs.eof())
{
ifs >> c[i];
i++;
}
}
cout<<"How many names do you want to enter?"<<endl;
cin>>numNames;
for(int l = i-1; l<numNames+i-1; l++)
{
system("cls");
cout<<"Enter a name: ";
cin>>c[l];
}
while(sorted == false)
{
for(int j = 0; j<numNames+i-1; j++)
{
for(int k = j; k<numNames+i-1; k++)
{
if(c[j][0] > c[k][0])
{
char snorre[20];
strcpy(snorre,c[j]);
strcpy(c[j],c[k]);
strcpy(c[k],snorre);
}
else if(c[j][0] == c[k][0])
{
if(c[j][1] > c[k][1])
{
char snorre[20];
strcpy(snorre,c[j]);
strcpy(c[j],c[k]);
strcpy(c[k],snorre);
}
}
}
}
cout<<endl<<endl<<endl;
ofstream ofs;
ofs.open("namn.txt");
for(int o = 0; o<numNames+i-1; o++)
{
cout<<c[o]<<" ";
ofs<<c[o]<<endl;
}
ofs.close();
system("pause");
sorted = true;
}
}
So hopefully someone could help me out with this problem, thanks in advance! :)
To get your code to use pointers and functions, you can do this- you should change your code and make it use the following:
First, Get each name from the file to an std::string, using getline(ifstream_object, std::string_object), for reference see here.
Convert each one to a const char * (also shown in that example), using .c_str().
Do the following to each of the new names entered.
Store all names entered in this array pointers: char *names[20];, like this: names[i] = name;
Next, Create a function such as follows:
int location_of_bigger_string(const char* s1, const char* s2)
{
// Returns 1 if s1 should be before s2 and 2 otherwise
// This way, you use functions and pointers together.
// Use strcmp(s1,s2) here to determine returning value
}
strcmp(char*, char*) - read about it here.
Finally, to sort all the strings, use qsort or this example.
Here's the complete code,
Note that the compare function gets pointers to the elements, here the elements are pointers themselves, so what's passed to "compare" function is of type "char **"
{
#include "stdafx.h"
#include<iostream>
//retruns +1 if str1 > str2 alphabetically
int compare(const void * a, const void * b )
{
const char * str1 = *((const char **)a);
const char * str2 = *((const char **)b);
int i;
for ( i = 0 ; str1[i] && str2[i] ; i++ )
{
if ( str1[i] > str2[i] )
{
return +1;
}
else if ( str1[i] < str2[i] )
{
return -1;
}
}
//one or both strings have ended
if (str1[i]) //str1 is longer
return +1;
else if (str2[i]) //str2 is longer
return -1;
else
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
char * names[]={"Zebra","Kousha","Koosha","Kou","Koush","Test"};
qsort( names, 6, sizeof(char *), compare );
return 0;
}
}
I'm sorting an array of names and my IDE is giving me "no matching function for call to 'strcpy'.
Here are the values I set up:
char Names [MaxNames] [MaxCharsPerName + 1];
const int MaxNames (20);
const int MaxCharsPerName (15);
Here is my function
void SortNames (const char Names[][MaxCharsPerName + 1], int NumNames)
{
int i;
int NumElements;
bool Sorted;
char Temp; // size 15?
NumElements = NumNames;
do {
Sorted = true;
NumElements--;
for (i = 0; i < NumNames; i++)
{
if(Names[i-1] > Names[i]){
strcpy(Temp, Names[i]);
strcpy(Names[i], Names[i+1]);
strcpy(Names[i+1], Temp);
}
}
} while (!Sorted);
Do I have to use a reference or something?
Oh and these are at the top:
include
using namespace std;
#include "Constants.h"
#include "Functions.h"
#include <string.h>
#include <stdio.h>
char Temp; // size 15?
Temp is a char and strcpy expects a char *(and compiler will give a compilation error in your case).
Use a char array instead-
char Temp[MaxCharsPerName + 1]; // any desired size but reserve place for '\0'
And then pass it to strcpy.
Sorting an array of names could be done much easier:
vector<string> names;
// ...
sort(begin(names), end(names), less<string>());
for (const auto& name : names) cout << name << '\n';
So, i have to do this project for college. I have to write a program that manages the orders of a pizza restaurant. so far this is what i have done :
#include <iostream>
#include <array>
#include <string>
#include <cctype>
#include <cmath>
#include <locale>
#include <algorithm>
using namespace std;
const int MAX_INGREDIENTES_PIZZA=10;
const int MAX_PEDIDOS=20;
enum TIngrediente
{
TOMATE,
QUESO,
NATA,
CEBOLLA,
POLLO,
HUEVO,
SALAMI,
ANCHOA,
BACON,
GAMBA
};
struct TPedido
{
string nombre_cliente;
int telefono;
int numero_pedido;
int numero_ingredientes;
TIngrediente ingredientes;
};
typedef array<float, MAX_PEDIDOS> listado_pedidos;
const array<string, MAX_INGREDIENTES_PIZZA> TIngredientes2 = {{"tomate", "queso", "nata", "cebolla", "pollo", "huevo", "salami", "anchoa", "bacon", "gamba"}};
TIngrediente StrToIngrediente(string s);
string IngredienteTostr(TIngrediente c);
string tolower(string s);
string tolower(string s)
{
string r = s;
for (int i = 0; i < s.size(); ++i)
r[i] = tolower(r[i]);
return r;
}
TIngrediente StrToIngrediente(string s)
{
s=tolower(s);
int i;
while (i < TIngredientes2.size() and TIngredientes2[i] != s)
++i;
return (TIngrediente)i;
}
string IngredienteTostr(TIngrediente c)
{
return TIngredientes2[c];
}
TIngredientes2 leer_ingrediente()
{
TIngredientes2 r;
for (int i=0; i<MAX_INGREDIENTES_PIZZA;i++){
cin>>r[i];
r[i]=tolower(r[i]);
}
StrToIngrediente(TIngredientes2);
return r;
}
TIngredientes2 escribir_ingrediente()
{
TIngredientes2 s;
for(int i=0; i<s.size(); i++){
cout<<s[i]<<endl;
}
return s;
}
TPedido leer_pedido()
{
TPedido p;
string ingredientes;
bool ok=true;
getline (cin, p.nombre_cliente);
cin >> p.telefono;
cin >> p.numero_pedido;
cin >> p.numero_ingredientes;
cin.ignore(100,'\n');
//getline (cin, p.ingredientes);
StrToIngrediente(ingredientes);
//necesitamos inicializar la variable booleana
if( numero_ingredientes > MAX_INGREDIENTES_PIZZA)
ok=false;
else if (numero_pedido > MAX_PEDIDOS)
ok=false;
else if (ingredientes != TIngrediente[i])
ok=false;
return p;
}
OK, But im having a few issues :
1) i have declared TIngredientes2 as an array, but the compiler says to me Tingredientes2 does not name a type.
2) I have managed to write the functions that transforms String in TIngrediente (enum) and viceversa, but now i have to make 2 functions to read keyboard input/write in screen and i dunno how to use those functions. I have writen something below but i dont know if it is ok.
3) When it comes to read keyboard input in leer_pedido() i dont know if that is ok because of the struct and most important, i have no idea how to use the boolean to say if the data introduced is correct or not.
4) The next fuction consist in storing the data from the last fucntion leer_pedido() in a list, and i have no clue.
I hope someone can help me
1) Function can't return an object of type 'Ttingrediente2' if you haven't already made class of type 'Tingrediente2'.
In your function :
TIngredientes2 escribir_ingrediente()
{
TIngredientes2 s;
for(int i=0; i<s.size(); i++){
cout<<s[i]<<endl;
}
You're declaring variable 'Tingredientes s' and after it,you're printing it out on the screen but it hasn't got size (there are no elements inside s).
Try like this:
void escribir_ingrediente(array<string,MAX_INGREDIENTES_PIZZA> s)
{
for(int i=0; i<s.size(); i++)
cout<<s[i]<<endl;
}
where you are passing already existing array to a function and it's printing out elements of s array.
2) Just read more about enumerations,iterating over them and inserting new elements.
3) You're using boolean variable on the beginning of testing your user's input.Something like:
bool good_Input = true; // suppose user's input is ok
if( p.numero_ingredientes > MAX_INGREDIENTES_PIZZA || p.numero_pedido > MAX_PEDIDOS)
good_input=false; // input is not good if there is more ingredients than max number of ingredients
if(good_Input)
cout<<"Input is good"<<endl;
else cout << "Input is not good"<<endl;
Therefore,you are leading boolean variable through your code so if there may be a mistake,you change it's value to 'false' and it will be 'false' to the end so you will know how to handle it further in code.
4) Storing structure's data in vector is the most easiest way to do that:
vector<Tpedido> structuresVector;
sturcturesVector.push_back(leer_pedido());
leer_pedido function returns 'Tpedido' type so you can insert it in vector directly
I wrote a simple C++ program to reverse a string. I store a string in character array. To reverse a string I am using same character array and temp variable to swap the characters of an array.
#include<iostream>
#include<string>
using namespace std;
void reverseChar(char* str);
char str[50],rstr[50];
int i,n;
int main()
{
cout<<"Please Enter the String: ";
cin.getline(str,50);
reverseChar(str);
cout<<str;
return 0;
}
void reverseChar(char* str)
{
for(i=0;i<sizeof(str)/2;i++)
{
char temp=str[i];
str[i]=str[sizeof(str)-i-1];
str[sizeof(str)-i-1]=temp;
}
}
Now this method is not working and, I am getting the NULL String as result after the program execution.
So I want to know why I can't equate character array, why wouldn't this program work. And what is the solution or trick that I can use to make the same program work?
sizeof(str) does not do what you expect.
Given a char *str, sizeof(str) will not give you the length of that string. Instead, it will give you the number of bytes that a pointer occupies. You are probably looking for strlen() instead.
If we fixed that, we would have:
for(i=0;i<strlen(str)/2;i++)
{
char temp=str[i];
str[i]=str[strlen(str)-i-1];
str[strlen(str)-i-1]=temp;
}
This is C++, use std::swap()
In C++, if you want to swap the contents of two variables, use std::swap instead of the temporary variable.
So instead of:
char temp=str[i];
str[i]=str[strlen(str)-i-1];
str[strlen(str)-i-1]=temp;
You would just write:
swap(str[i], str[sizeof(str) - i - 1]);
Note how much clearer that is.
You're using C++, just use std::reverse()
std::reverse(str, str + strlen(str));
Global variables
It's extremely poor practice to make variables global if they don't need to be. In particular, I'm referring to i about this.
Executive Summary
If I was to write this function, it would look like one of the two following implementations:
void reverseChar(char* str) {
const size_t len = strlen(str);
for(size_t i=0; i<len/2; i++)
swap(str[i], str[len-i-1]);
}
void reverseChar(char* str) {
std::reverse(str, str + strlen(str));
}
When tested, both of these produce dlrow olleh on an input of hello world.
The problem is that within your function, str is not an array but a pointer. So sizeof will get you the size of the pointer, not the length of the array it points to. Also, even if it gave you the size of the array, that is not the length of the string. For this, better use strlen.
To avoid multiple calls to strlen, give the function another parameter, which tells the length:
void reverseChar(char* str, int len)
{
for(i=0; i<len/2; i++)
{
char temp=str[i];
str[i]=str[len-i-1];
str[len-i-1]=temp;
}
}
and call it with
reverseChar(str, strlen(str))
Another improvement, as mentioned in the comments, is to use std::swap in the loop body:
void reverseChar(char* str, int len)
{
for(i=0; i<len/2; i++)
{
std::swap(str[i], str[len-i-1]);
}
}
Also, there is std::reverse which does almost exactly that.
//reverse a string
#include<iostream>
using namespace std;
int strlen(char * str) {
int len = 0;
while (*str != '\0') {
len++;
str++;
}
return len;
}
void reverse(char* str, int len) {
for(int i=0; i<len/2; i++) {
char temp=str[i];
str[i]=str[len-i-1];
str[len-i-1]=temp;
}
}
int main() {
char str[100];
cin.getline(str,100);
reverse(str, strlen(str));
cout<<str<<endl;
getchar();
return 0;
}
If I were you, I would just write it like so:
int main()
{
string str;
cout << "Enter a string: " << endl;
getline(cin, str);
for (int x = str.length() - 1; x > -1; x--)
{
cout << str[x];
}
return 0;
}
This is a very simple way to do it and works great.
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
char str[80];
cout << "Enter a string bro: \n";
gets_s(str);
for (int i = strlen(str) - 1; i > -1; i--)
{
cout << str[i];
}
}
Can someone help me with this: This is a program to find all the permutations of a string of any length. Need a non-recursive form of the same. ( a C language implementation is preferred)
using namespace std;
string swtch(string topermute, int x, int y)
{
string newstring = topermute;
newstring[x] = newstring[y];
newstring[y] = topermute[x]; //avoids temp variable
return newstring;
}
void permute(string topermute, int place)
{
if(place == topermute.length() - 1)
{
cout<<topermute<<endl;
}
for(int nextchar = place; nextchar < topermute.length(); nextchar++)
{
permute(swtch(topermute, place, nextchar),place+1);
}
}
int main(int argc, char* argv[])
{
if(argc!=2)
{
cout<<"Proper input is 'permute string'";
return 1;
}
permute(argv[1], 0);
return 0;
}
Another approach would be to allocate an array of n! char arrays and fill them in the same way that you would by hand.
If the string is "abcd", put all of the "a" chars in position 0 for the first n-1! arrays, in position 1 for the next n-1! arrays, etc. Then put all of the "b" chars in position 1 for the first n-2! arrays, etc, all of the "c" chars in position 2 for the first n-3! arrays, etc, and all of the "d" chars in position 3 for the first n-4! arrays, etc, using modulo n arithmetic in each case to move from position 3 to position 0 as you are filling out the arrays.
No swapping is necessary and you know early on if you have enough memory to store the results or not.
A stack based non-recursive equivalent of your code:
#include <iostream>
#include <string>
struct State
{
State (std::string topermute_, int place_, int nextchar_, State* next_ = 0)
: topermute (topermute_)
, place (place_)
, nextchar (nextchar_)
, next (next_)
{
}
std::string topermute;
int place;
int nextchar;
State* next;
};
std::string swtch (std::string topermute, int x, int y)
{
std::string newstring = topermute;
newstring[x] = newstring[y];
newstring[y] = topermute[x]; //avoids temp variable
return newstring;
}
void permute (std::string topermute, int place = 0)
{
// Linked list stack.
State* top = new State (topermute, place, place);
while (top != 0)
{
State* pop = top;
top = pop->next;
if (pop->place == pop->topermute.length () - 1)
{
std::cout << pop->topermute << std::endl;
}
for (int i = pop->place; i < pop->topermute.length (); ++i)
{
top = new State (swtch (pop->topermute, pop->place, i), pop->place + 1, i, top);
}
delete pop;
}
}
int main (int argc, char* argv[])
{
if (argc!=2)
{
std::cout<<"Proper input is 'permute string'";
return 1;
}
else
{
permute (argv[1]);
}
return 0;
}
I've tried to make it C-like and avoided c++ STL containers and member functions (used a constructor for simplicity though).
Note, the permutations are generated in reverse order to the original.
I should add that using a stack in this way is just simulating recursion.
First one advice - don't pass std:string arguments by value. Use const references
string swtch(const string& topermute, int x, int y)
void permute(const string & topermute, int place)
It will save you a lot of unnecessary copying.
As for C++ solution, you have functions std::next_permutation and std::prev_permutation in algorithm header. So you can write:
int main(int argc, char* argv[])
{
if(argc!=2)
{
cout<<"Proper input is 'permute string'" << endl;
return 1;
}
std::string copy = argv[1];
// program argument and lexically greater permutations
do
{
std::cout << copy << endl;
}
while (std::next_permutation(copy.begin(), copy.end());
// lexically smaller permutations of argument
std::string copy = argv[1];
while (std::prev_permutation(copy.begin(), copy.end())
{
std::cout << copy << endl;
}
return 0;
}
As for C solution, you have to change variables types from std::string to char * (ugh, and you have to manage memory properly). I think similar approach - writing functions
int next_permutation(char * begin, char * end);
int prev_permutation(char * begin, char * end);
with same semantics as STL functions - will do. You can find source code for std::next_permutation with explanation here. I hope you can manage to write a similar code that works on char * (BTW std::next_permutation can work with char * with no problems, but you wanted C solution) as I am to lazy to do it by myself :-)
Have you tried using the STL? There is an algorithm called next_permutation which given a range will return true on each subsequent call until all permutations have been encountered. Works not only on strings but on any "sequence" type.
http://www.sgi.com/tech/stl/next_permutation.html
This solves the problem without recursion. The only issue is that it will generate duplicate output in the case where a character is repeated in the string.
#include<iostream.h>
#include<conio.h>
#include<stdio.h>
#include<string.h>
int factorial(int n)
{
int fact=1;
for(int i=2;i<=n;i++)
fact*=i;
return fact;
}
char *str;
void swap(int i,int j)
{
char temp=str[i];
str[i]=str[j];
str[j]=temp;
}
void main()
{
clrscr();
int len,fact,count=1;
cout<<"Enter the string:";
gets(str);
len=strlen(str);
fact=factorial(len);
for(int i=0;i<fact;i++)
{
int j=i%(len-1);
swap(j,j+1);
cout<<"\n"<<count++<<". ";
for(int k=0;k<len;k++)
cout<<str[k];
}
getch();
}
#include <iostream>
#include <string>
using namespace std;
void permuteString(string& str, int i)
{
for (int j = 0; j < i; j++) {
swap(str[j], str[j+1]);
cout << str << endl;
}
}
int factorial(int n)
{
if (n != 1) return n*factorial(n-1);
}
int main()
{
string str;
cout << "Enter string: ";
cin >> str;
cout << str.length() << endl;
int fact = factorial(str.length());
int a = fact/((str.length()-1));
for (int i = 0; i < a; i++) {
permuteString(str, (str.length()-1));
}
}