I am trying to create a function that prints the elements of an array. I set it up so it calculates the size of the array, but I cannot figure why it doesn't work. Can you give me some suggestions?
Thanks!
#include <iostream>
#include <string>
using namespace std;
void print_array(string s){
for(int i = 0; i < ( sizeof(s) / sizeof(s[0]) ); i++){
cout << s[i] << "\n";
}
}
int main()
{
string names[5] = {"Dante", "Greg", "Bob", "Victor", "Saber"};
print_array(names);
}
Welcome to Stack Overflow! Be aware that there are many questions similar to this that have received answers.
As mentioned in a comment, you would need to specify the size of the array if you plan on passing it into a function, because the compiler will look at it not as an array of strings (string s[]), but as a pointer to strings (string s*). Thus, you would need to modify it a little like so:
#include <iostream>
#include <string>
using namespace std;
void print_array(string s[], int size){
for(int i = 0; i < size; i++)
{
cout << s[i] << "\n";
}
}
int main()
{
string names[5] = {"Dante", "Greg", "Bob", "Victor", "Saber"};
print_array(names, sizeof(names) / sizeof(names[0]));
}
You are passing a string instead of an array of strings. You could modify your code by using vectors like this:
void print_array(const std::vector<std::string> &vector){
for (const auto &string : vector) {
std::cout << string << "\n";
}
}
int main()
{
std::vector<std::string> names = {"Dante", "Greg", "Bob", "Victor", "Saber"};
print_array(names);
}
Using vectors allows you to use auto generated for loops, wich are easy to read and use.
Related
I'm having a problem filling a special array of strings in an automated way.
The strings must be as follows: "01", "012", etc. until you get to "012...XYZ".
I had thought of making a "reference" string like this: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" to be able to browse it and create the other strings based on it but I think there are simpler ways and I can't manage to implement this system.
Thanks in advance!
Just browse the reference string and create the substrings. For that, using std::string::substr is rather useful.
Difficult to get an easier solution.
#include <iostream>
#include <vector>
#include <string>
std::vector<std::string> get_subs(const std::string &ref) {
int n = ref.size();
std::vector<std::string> vec;
for (int i = 2; i <= n; ++i) {
vec.emplace_back (ref.substr(0, i));
}
return vec;
}
int main () {
std::string ref = "01234567";
std::vector<std::string> res = get_subs (ref);
for (std::string &s: res) {
std::cout << s << " ";
}
std::cout << "\n";
}
im currently setting up the highscore-part for a game and I have a very weird problem because of the weird behaviour of the std::sort function.
Im doing the whole thing in RAD Studio 10.2 (Embarcadero IDE) in C++.
So he is my code:
std::string Line;
int count = 0;
int i = 0;
ifstream File("Highscore.txt");
if(File.is_open())
{
while(getline(File, Line))
{
count += 1;
}
File.close();
}
ifstream ReadFile("Highscore.txt");
if(ReadFile.is_open())
{
string *scores = NULL;
scores = new string[count];
while(getline(ReadFile, Line))
{
scores[i] = Line;
i += 1;
}
ReadFile.close();
std::sort(scores, (scores+count));
UnicodeString Uscores1 = scores[0].c_str();
UnicodeString Uscores2 = scores[1].c_str();
UnicodeString Uscores3 = scores[2].c_str();
UnicodeString Uscores4 = scores[3].c_str();
UnicodeString Uscores5 = scores[4].c_str();
LScore1->Caption = Uscores1;
LScore2->Caption = Uscores2;
LScore3->Caption = Uscores3;
LScore4->Caption = Uscores4;
LScore5->Caption = Uscores5;
}
I get no errors from the compiler/linker and everything work should fine.
The string array gets filled correctly and so on.
But its not sorting.
To show the problem to you I made a screenshot - on the left you can see the txtfile with the scores; on the right you can see the output after the sorting algorithm:
My question now is why this is happening?
Thanks for you help
Welcome to C++. Since you want to list numbers by rank, read them as int not string. Forget about operator new. You will not need it for years, if ever. Use standard containers like std::vector, which take care of the memory allocation and de-allocation transparently.
#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm>
int main() {
using namespace std;
vector<int> scores;
{
ifstream inp("Highscore.txt");
int next;
while (inp >> next) {
scores.push_back(next);
}
}
sort(scores.begin(), scores.end());
for (auto s : scores) {
cout << s << '\n';
}
return 0;
}
How about something like:
int i = 0;
int * scoresInteger = NULL;
scoresInteger = new int[count];
for(i = 0; i < count; i++)
{
scoresInteger[i] = std::stoi(scores[i]);
}
std::sort(scoresInteger, scoresInteger + count);
If you need to, you can convert the integers back into strings using targetStrings[i] = std::to_string(scoresInteger[i]).
string * targetScores = NULL;
targetScores = new std::string[count];
for(i = 0; i < count; i++)
{
targetScores[i] = std::to_string(scoresInteger[i]);
}
delete [] scoresInteger;
scoresInteger = NULL;
Don't forget to delete [] targetScores later.
My question now is why this is happening?
Because your scores are compared as strings and not as ints. Because of that "3" is greater that "25"
std::cout << std::boolalpha << (std::string("3") > std::string("25")) << std::endl; // true
Luckily you can pass a custom comparator (or lambda) to the std::sort to make it behave just as you want:
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
const int count = 5;
std::string scores[count] = { "35","25","3","4","5" };
// TWEAKED SORT
std::sort(scores, scores + count, [](std::string const &s1, std::string const &s2)
{
return std::stoi(s2) < std::stoi(s1);
});
// TEST
for (auto const &s : scores)
{
std::cout << s << std::endl;
}
}
The compared strings in the above example are converted to ints and then compared, resulting in the desired sorting order.
35
25
5
4
3
Please note that I do not agree with the rest of your code and I think you should rethink the implementation, as it would be much easier, safer and more efficient to use std::vector<std::string> for your task.
Given an array of the form
char* timePeriod= {"6AM#8AM","11AM#1PM","7AM#3PM","7AM#10AM","10AM#12PM"};
how can I extract the start and end time in integer arrays of following form:
start_time={6,11,7,7,10}
end_time={8,1,3,10,12}
You can use "sscanf" to do so. And don't forget to mark it as useful :)
#include <stdio.h>
int main()
{
int a,b,i;
int start_time[5], end_time[5];
char *t[5] = {"6AM#8AM","11AM#1PM","7AM#3PM","7AM#10AM","10AM#12PM"};
char *(*ptr)[5] = &t;
for(i=0;i<5;i++)
{
sscanf((*ptr)[i], "%d%*[AP]M#%d%*[AP]M", &a, &b);
start_time[i]=a;
end_time[i]=b;
}
printf("Starting time : ");
for(i=0;i<5;i++)
{
printf("%d ",start_time[i]);
}
printf("\nEnding time : ");
for(i=0;i<5;i++)
{
printf("%d ",end_time[i]);
}
return 0;
}
OUTPUT:
Starting time : 6 11 7 7 10
Ending time : 8 1 3 10 12
A pretty simple way would be to use strtok to split the string on the #, then use atoi on each piece. It will stop once it sees a non-numeric value.
sscanf is capable of doing this, although I don't think it's a very good way. look at here for details
#include <stdio.h>
int main() {
const char* t = "6PM#8AM";
int a, b;
sscanf(t, "%d%*[AP]M#%d%*[AP]M", &a, &b);
printf("%d %d\n", a, b);
return 0;
}
or you can regex in C++11
#include <iostream>
#include <regex>
#include <string>
using namespace std;
int main() {
string t("6PM#8AM");
smatch match;
regex re("([[:digit:]])+[AP]M#([[:digit:]])+[AP]M");
if (regex_match(t, match, re)) {
cout << match[1].str() << " " << match[2].str() << '\n';
}
return 0;
}
Note: the following solution makes a few very specific assumptions about your dataset (if these are not the case, you may prefer using a regex).
The string will always start with integers
The endtimes will always either be in the 4th or 5th index of your string
Zero is not a valid time
#include <iostream>
#include <string>
int main() {
std::string timePeriod[5] = {"6AM#8AM","11AM#1PM","7AM#3PM","7AM#10AM","10AM#12PM"};
int startTimes[5] = {0,0,0,0,0};
int endTimes[5] = {0,0,0,0,0};
for(int i=0;i<5;i++) {
std::string s = timePeriod[i];
startTimes[i] = atoi(s.c_str()); // Convert first number to integer
endTimes[i] = atoi(s.substr(4).c_str()); // Convert 2nd numbers to integer
if(endTimes[i] == 0) // If zero
endTimes[i] = atoi(s.substr(5).c_str()); // Get the 5th index instead
std::cout << "Start: " << startTimes[i] << "\t End: " << endTimes[i] << std::endl;
}
}
The lack of leading zeros makes it a bit trickier, but ultimately - it can be quickly solved using substrings (assuming also you don't mind changing the char* into a std::string).
Let's say I have an array
string test = {"test1, "test2"}
I have my function
void testing(string test){
for(int i = 0; i < 2; i++){
if(test[i] == "test1"){
cout << "success" << endl;
}
}
}
But when I compile this, I get an error...why is that?
Is there a different approach?
Your test variable should be declared as an array type
string test[] = {"test1", "test2"};
You also need to change the function signature from
void testing(string test)
to
void testing(string* test){
the code you wrote is not going to compile because of wrong declaration of string array.
replace
string test = {"test1, "test2"};
with
string test[]={"test1, "test2"};
The following code uses the array in place without function
#include <iostream>
#include <string>
using namespace std;
string test[]={"test1, "test2"};
for(auto& item:test)
{
cout<<item<<endl;
}
I think the best way to get this working with function is to use vector
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void testing(const vector<string>& strings)
{
for (auto& item : strings)
{
cout << item << endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<string> strings = { "str1", "str2", "str3" };
testing(strings);
cin.get();
return 0;
}
I am having trouble with my method. I want it to accept an array of strings as its first argument instead of a vector string. However when I try to use an Array of strings and make one in the main function I get all kinds of errors. I don't know if I should user a pointer to an array of strings for my argument or just a string. Any help?
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <sstream>
#include<iostream>
using namespace std;
class UserName
{
public:
string newMember(string* exist, string newname) {
bool found = false;
bool match = false;
stringstream ss;
string result;
string othername;
for(int i = 0; i < exist.size(); i++){
if(exist[i] == newname){
found = true;
break;
}
}
if(found){
for(int x = 1; ; x++){
match = false;
ss.str("");
ss << newname << x;
for(int i = 0; i < exist.size();i++){
//cout << ss.str() << endl;
othername = ss.str();
if(exist[i] == othername){
match = true;
break;
}
}
if(!match){
result = ss.str();
break;
}
}
return result;
}
else return newname;
}
};
int main(){
UserName u;
string Database [4];
Database[0] == "Justin";
Database[1] == "Justin1";
Database[2] == "Justin2";
Database[3] == "Justin3";
cout << u.newMember(Database, "Justin") << endl;
return 0;
}
Arrays in C++ are unfortunately a special case, and in many ways do not behave like proper values. A few examples:
void foo(int c[10]); // looks like we're taking an array by value.
// Wrong, the parameter type is 'adjusted' to be int*
int bar[3] = {1,2};
foo(bar); // compile error due to wrong types (int[3] vs. int[10])?
// No, compiles fine but you'll probably get undefined behavior at runtime
// if you want type checking, you can pass arrays by reference (or just use std::array):
void foo2(int (&c)[10]); // paramater type isn't 'adjusted'
foo2(bar); // compiler error, cannot convert int[3] to int (&)[10]
int baz()[10]; // returning an array by value?
// No, return types are prohibited from being an array.
int g[2] = {1,2};
int h[2] = g; // initializing the array? No, initializing an array requires {} syntax
h = g; // copying an array? No, assigning to arrays is prohibited
(taken from here)
If you want an array that behaves like a proper value use std::array.
#include <array>
#include <string>
void foo(std::array<std::string, 10> arr) { /* ... */ }
int main() {
std::array<std::string, 10> arr = {"Justin", "Justin1", "Justin2", "Justin3"};
foo(arr);
}
Use like following:
std::string Database[] ={ "Justin", "Justin1", "Justin2","Justin3" };
newmember as
string newMember(std::string exist[], std::size_t n, string newname)
replace exist.size() with n
In main :
cout << u.newMember(Database, 4,"Justin") << endl;
Also as per your edited post
The operator = is not the same as the operator ==, the first one is an assignment operator (assigns the value at its right to the variable at its left) and the other one == is the equality operator
So you need to use as:
Database[0] = "Justin";
Database[1] = "Justin1";
Database[2] = "Justin2";
Database[3] = "Justin3";