I've Googled, asked my classmates, and finally asked my professor about this particular problem, but I haven't achieved a solution yet. I'm hoping someone here can help me out.
Basically, I need to make an array of structs that will contain 4 pieces of information per struct: country name, country population, country area, and country density. This information will be written to the structs in the array from a .txt document. This info will then be written onto the console from said array.
Unfortunately, in attempting to write anything to the structs in the array, I get 2 errors. "Cannot convert from 'const char[8]' to 'char [30]'" and "no operator '[]' matches these operands, operand types are: CountryStats [int]". These errors both refer to the line:
countries[0].countryName = "A";
Keep in mind that I have only started to use structs and this is the first time I've used them in an array. Also, I must use an array, as opposed to a vector.
Here's my code:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
struct CountryStats;
void initArray(CountryStats *countries);
const int MAXRECORDS = 100;
const int MAXNAMELENGTH = 30;
struct CountryStats
{
char countryName[MAXNAMELENGTH];
int population;
int area;
double density;
};
// All code beneath this line has been giving me trouble. I need to easily edit the
// struct variables and then read them.
int main(void)
{
CountryStats countries[MAXRECORDS];
initArray(*countries);
}
void initArray(CountryStats countries)
{
countries[0].countryName = "A";
}
As of now I am just attempting to figure out how to write information to a struct within the array and then read the information off of it onto the console. Everything else should fall into place after I find the solution to this.
Oh, and one final note: I have not quite learned the function of pointers (*) yet. I am still relatively new to C++ as my past programming education has been primarily in Java. Any and all inclusions of pointers in this code have been influenced by my classmates and professor in the pursuit of solving this problem.
Thanks in advance!
Two problems
void initArray(CountryStats countries)
must be:
void initArray(CountryStats *countries)
And you must use strcpy to copy c style string. (but i suggest to use c++ string instead of char[])
strcpy(countries[0].countryName,"A");
But I say again, use c++ features like vector<> and string.
You are not defining a definition for:
void initArray(CountryStats *countries);
but for:
void initArray(CountryStats countries);
in which countries is not an array. Since no operator[] is defined for CountryStats, the expression countries[0] fails to compile.
Since you cannot use std::vector (for some weird reasons), I'd suggest you to use an std::array:
template<std::size_t N>
void initArray(std::array<CountryStats, N>& ref) {
for (std::size_t i = 0; i < N; i++)
// initialize ref[i]
}
Of course, if you feel masochist, you can also use a C-style array:
void initArray(CountryStats* arr, int size) {
for (int i = 0; i < size; i++)
// initialize arr[i]
}
But you'll, probably, need to provide the dimension of the array as a second parameter.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm having a problem when i try to use a char[20] array and put it's "content" into another array of same size.
struct book{
char author[20];
char title[20];
};
book library [100];
void removebook(){
for (cont; cont<=quantidade; cont++){
cont2=(cont+1);
// HERE is where all goes downhill ↓↓↓↓↓↓↓↓↓↓↓
library[cont].author = library[cont2].author
}
the error i get is [Error] invalid array assignment
the intention is make a author name written on library[4].author overwrite library[3].author
like:
library[4].author=Mark;
library[3].author = library[4].author;
now whatever was on library[3].author was overwritten with mark
You can't copy an array with operator=. You can fix your problem using modern C++
#include <array>
#include <cstddef>
// #include <list>
#include <string>
// #include <vector>
struct book{
std::string author;
std::string title;
};
std::array<book, 100> library; // or std::vector<book> library;
// or std::list<book> library;
void removebook(std::size_t idx) {
for (std::size_t cont = idx; cont < library.size() - 1; ++cont){
std::size_t cont2 = cont + 1;
library[cont] = library[cont2];
}
}
Probably you can replace the body of removebook with a function from algorithm like std::remove or a method like std::vector::erase or std::list::erase depending on how you implement it, e.g. for std::array<book, 100> library
#include <array>
#include <cstddef>
#include <string>
struct book{
std::string author;
std::string title;
};
std::array<book, 100> library;
void removebook(std::size_t idx) {
std::copy(library.begin() + idx + 1, library.end(), library.begin() + idx);
library.back() = book{};
}
When your attribute is defined as traditional C char array, your = operator between two traditional C char array will try to assign the right side first array address to the left side argument because library[cont].author is actually contains a constant char address in the memory.
The line:
library[cont].author = library[cont2].author;
Actually tries to take library[cont2].author value, which is constant char address, and assign it to library[cont].author which is also constant char address (which cause the failure). Even if it would work, it wouldn't done what you want it to.
The closest way to archive what it would done if it worked, is to define author as char*. Assume we allocated a memory for this attribute in every member of the library. The same line of code, would make all of the pointers to contains the same memory address, and now you can see how much troubles it would done.
The solution can be use std::string as mentioned in #ThomasSablik answer or as #Peter mentioned std::array<char, 20>.
I have been given following assignment
Write a simple telephone directory program; contain two dimensional arrays in which you have hard code names and telephone number. Then declare a simple character array. You have to prompt user to enter any name, which you want to search. This name should be store in this character array, then search this name from the two dimensional array. If number is found against entered name then program should display the number against this name, and if not found then program should display the message that name is not registered.
Here is my code but i could not get the number when i search for the name. I am new to coding so i am having trouble making this code work. Help is appreciated.
#include <iostream>
#include <conio.h>
using namespace std;
int getPhone(int p[5][10],int row, int col, char key[10],char n[5][10]);
int main() {
int i,j;
char search[10];
const int r = 5;
const int c = 10;
int element;
int phone[r][c] =
{
42-5429874,
42-5333156,
42-9824617,
42-9927562,
42-6238175
};
char name[r][c] = {"shazia","zara","sana","ahmad","maha"};
cout<<"\nEnter name to find in directory : ";
cin>>search[r];
element = getPhone(phone,r,c,search,name);
cin.get();
return 0;
}
int getPhone(int p[5][10],int row,int col,char key[10], char n[5][10]) {
int i, j;
for(i=0;i<row;i++)
for(j=0;j<col;j++)
p[5][10] = p[i][j];
if(key[j] = n[5][10])
cout<<"The desired number is: "<<p[i][j]<<endl;
else if(key[j]!=n[5][10])
cout<<"Sorry! This name is not registered.";
return p[i][j];
}
Your code contains several mistakes. Let's examine them.
for(i=0;i<row;i++)
for(j=0;j<col;j++)
p[5][10] = p[i][j];
Here, you make no change on your array, because just the value of p[5][10] is changed. Furthermore, you access an invalid memory zone, because array indexes go from 0 to size - 1 in C++. So last index is p[4][9].
if(key[j] = n[5][10])
In C++, comparing two values needs two =, because only one is an affectation that results the if to be always true. A tip to remember: two values to compare need two =.
else if(key[j]!=n[5][10])
The same than before, you access invalid memory zone. And are you sure that j is valid, e.g less than 10 ? If not, you do double invalid access.
cin>>search[r];
As search is an array of char, you do an input of only a single char there, which I think is not what you want and that can leads to segfault.
int phone[r][c] =
{
42-5429874,
42-5333156,
42-9824617,
42-9927562,
42-6238175
};
Your array is not good, a simple 1-dimension array is enough, not 2-dimensions. Furthermore, 42-54.. does a subtraction, and I think is not what you want.
There are others mistakes. But why not using C++ abstractions, like std::vector, or std::string? Your life would get so much easier. But I guess you have an old teacher that never took time to learn C++ news, or that is not a good teacher.
As a beginner, I suggest you to read C++ Primer and Programming: Principles and Practice Using C++ to introduce you both programming and modern C++.
This question already has answers here:
C++ : Creating an array with a size entered by the user
(3 answers)
Closed 3 years ago.
I am trying to get a user input and set it as the PUZZLESIZE which is used by int peg and row but am getting the expression must have a constant value.
How would I go about getting a user input and setting it as a global const that struct Board will recognize?
int a;
const int PIECE = a;
const int PUZZLESIZE = ((PUZZLESIZE *(PUZZLESIZE+1)) /2);
typedef struct Board {
int *row[PUZZLESIZE];
int peg[PIECE];
int lastmove;
struct Board *prevBoard;
int prow;
int pcol;
} Board;
int main()
{
scanf("%d",a);
}
Thanks for any help in advanced
Re-setting the value of a const variable at runtime is not possible.
You just defined PIECE as a const (constant variable):
const int PIECE = a;
So, you cannot change the value of PIECE after starting the program.
You have to rethink a little about how your program will work. In addition since you are using C++ you may consider the use of the language features and libraries so that you can follow best practices as recommended by #Joren.
You have 2 options:
Option 1 : Make PuzzleSize your largest supported puzzle.
If you do this all you need to do is validate the user input against this size.
In addition you don't have to fiddle with memory allocation.
Simple solution
Potentially can have large segments of unused memory
Option 2: Make row a double pointer and use new to allocate your rows.
typedef struct Board
{
int **row; // int *row[PUZZLESIZE];
....
}
once the user sets the input you can validate the input and do this
int main()
{
scanf("%d",a);
row = new int*[a]; }
Don't forget to take a look at your C++ book and read up on const, multidimensional arrays ,and new.
Good Luck!
This question already has answers here:
Why can one specify the size of an array in a function parameter?
(3 answers)
Closed 3 years ago.
This feels like a really stupid thing to ask, but I had someone taking a programming class ask me for some help on an assignment and I see this in their code (no comments on the Hungarian notation please):
void read_dictionary( string ar_dictionary[25], int & dictionary_size ) {...
Which, as mainly a C# programmer (I learned about C and C++ in college) I didn't even know you could do. I was always told, and have read since that you're supposed to have
void read_dictionary( string ar_dictionary[], int ar_dictionary_size, int & dictionary_size ) {...
I'm told that the professor gave them this and that it works, so what does declaring a fixed size array like that even mean? C++ has no native way of knowing the size of an array being passed to it (even if I think that might've been changed in the newest spec)
In a one dimensional array It has no significance and is ignored by the compiler. In a two or more dimensional array It can be useful and is used by the function as a way to determine the row length of the matrix(or multi dimensional array). for example :
int 2dArr(int arr[][10]){
return arr[1][2];
}
this function would know the address of arr[1][2] according to the specified length, and also the compiler should not accept different sizes of arrays for this function -
int arr[30][30];
2dArr(arr);
is not allowed and would be a compiler error(g++) :
error: cannot convert int (*)[30] to int (*)[10]
The 25 in the parameter declaration is ignored by the compiler. It's the same as if you'd written string ar_dictionary[]. This is because a parameter declaration of array type is implicitly adjusted to a pointer to the element's type.
So the following three function declarations are equivalent:
void read_dictionary(string ar_dictionary[25], int& dictionary_size)
void read_dictionary(string ar_dictionary[], int& dictionary_size)
void read_dictionary(string *ar_dictionary, int& dictionary_size)
Even in the case of the first function, with the size of the array explicitly declared, sizeof(ar_dictionary) will return the same value as sizeof(void*).
See this sample on Codepad:
#include <string>
#include <iostream>
using namespace std;
void read_dictionary(string ar_dictionary[25], int& dictionary_size)
{
cout << sizeof(ar_dictionary) << endl;
cout << sizeof(void*) << endl;
}
int main()
{
string test[25];
int dictionary_size = 25;
read_dictionary(test, dictionary_size);
return 0;
}
Output (the exact value is, of course, implementation-dependent; this is purely for example purposes):
4
4
I always though that passing fixed size C++ arrays was a "half baked" feature of C++. For example, ignored size matching or only being able to specify the first index size, etc... Until recently I learn this idiom:
template<size_t N1, size_t N2> // enable_if magic can be added as well
function(double(&m)[N1][N2]){
... do something with array m...knowing its size!
}
Reference: Can someone explain this template code that gives me the size of an array?
This question was migrated 12 years ago.
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main (){
int a,b;
b = 0;
cout<<" this is a family profiling program to test my knowledge of structural arrays. ";
cin>> a;
struct p {
char name[20];
int age;
char hobby[40];
char favcolor[15];
};
p family[2];
**cin.getline(family.name[0]);**
cout<<"enter the name of family member"<<b+1;
I am trying to use this code to create a family profiling program, i know how to add value to an array or structural array during compiler time but not to use cin or cin.getline to add a value to to a specific value in a specific structure of an array.
please respond with a simple answer; Im still new to programming.(my attempt is bolded
If you insist on using an array, the easiest way to do this (add elements to a fixed-size array) would be to copy everything to a NEW array, including the new item.
A much better way would be to use a dynamic structure, such as a linked list. The standard template library and the boost library have many ways to help you here, but you could also easily implement a simple linked list on your own (or find code for it).
As Mike Chess said, this is probably best asked on http://www.stackoverflow.com
(also, to get your code formatted nicely, edit your post, select the code section, and click the button with the ones and zeros icon just above the text area)
Firstly, you'll find it much easier to write reliable code if you use std::string instead of character arrays. You were nearly on the right track though: instead of family.name[0] try family[0].name, then getline will work with std::string as below...
struct p
{
std::string name;
// other stuff...
};
if (getline(std::cin, family[0].name))
{
// it worked!
...
}
The "high performance" and old school option is to use realloc like this.
p * family = malloc(sizeof(p)*2);
family = realloc(family, sizeof(p)*13);
Of course this doesn't invoke constructors, and is not really acceptable in C++ generally. So your best option is.
#include <list>
using namespace std;
...
list<p> family;
p blah;
family.push_back(blah);
That's a linked list so it's perfect for datasets of unknown length. Same code can be used for an STL vector, which if you predict the size of your input in advance well enough will give you a performance boost.