Difficulties on atributting a array to another [closed] - c++

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>.

Related

Is there anyway for the array at the end of class to work? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I got an array at the end of my class and i don't know how to use it.
the bus[10] is so hard to understand. I don't know why it can access driver and what does empty() function really do.
#include "conio.h"
#include "stdio.h"
#include "iostream.h"
#include "string.h"
#include "graphics.h"
#include "stdlib.h"
#include "dos.h"
static int p=0;
class a
{
char driver[10];// driver
public:
void install();// for installing
}bus[10];//here we declare the number of buses we can have.
void a::install()
{
cout<<"Enter bus no: ";//ques
cin >> bus[p].driver;// what does this mean
bus[p].empty();//what does this mean
p++;
}
This is syntax for defining a type, and an instance of that type, at the same time.
For example:
struct Foo {} foo;
is the same as:
struct Foo {};
Foo foo;
So your example defines the type a, and also creates an array of 10 as called bus.
It would be more clearly written thus:
class a
{
char driver[10];
public:
void install();
};
a bus[10];
In this manner we can now more easily see that you've created a global array called bus, which you can use like you'd use any other array.
Since p is zero (to begin with), bus[p] just gives you the "first" a object in the array (to begin with). As p is increased, subsequent buses are accessed.
So, this:
cin >> bus[p].driver;
reads into the driver member of the pth bus.*
And this:
bus[p].empty();
means nothing, because a does not have a member function called empty().
* Well, the p+1th bus, because array indices begin at zero but English doesn't!
P.S. You can do funny (read: stupid) things with this syntax!
This is a very strange looking code, probably from an old workbook.
I could help you with achieving the action that you want, but it's hard to understand anything from this snippet.
Wrong: As far as I remember adding a identifier at the end of an unnamed struct gave it a name just like the usual approach.
struct {
float x, y;
} Point;
//is equal to
struct Point {
float x, y;
}
However I'm not familiar with the array syntax you provided.
I suppose std::cin >> bus[p].driver is meant to read the "name" that the char[10] driver field is. But using a char array here is troublesome and it's much better to replace it with std::string and shortening it to 10 characters after input.
The empty() method is often used as a container function returning boolean and telling the programmer whether the container is empty or not. Here however this function is undeclared and the code won't compile either way.
Not to mention that non-const variables placed out of function scope, like the static int p = 0, are a grave mistake.
Not true: In conclusion this is a very messy code and without the knowledge of what you want to achieve nobody could help you here.
See the answer below for better explanation.

Some problems with struct [closed]

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 6 years ago.
Improve this question
#include <iostream>
using namespace std;
struct student{
char name[10];
int grade;
};
int main() {
struct student s[10];
student s[0].name = "Jack";
cout<<s[0].name;
}
I want to create the struct type data student as an arraign. But when I did it like this, some errors appeared and I didn't know why.Following are the errors:
1.error: redefinition of 's' with a different type: 'student [0]' vs 'struct student [10]'
student s[0].name = "Jack";
^
2.note: previous definition is here
struct student s[10];
^
3. error: expected ';' at end of declaration
student s[0].name = "Jack";
^
;
char name[10];:
10 characters is too short for a name.
char assumes names are not outside ASCII or UTF-8, and it doesn't look like you're using a Unicode library.
Fixed-sized arrays for storing strings is not keeping with idiomatic C++.
Solution: use std::string or std::wstring - and use a Unicode library!
struct student s[10]
This is not idiomatic C++. The struct keyword is unnecessary. Just student s[10]; is sufficient.
Again, avoid fixed-sized arrays unless you know for certain you will be using 10 records. Use std::vector<student> instead.
You don't initialize the array, so the data-members will contain undefined/uninitialized data. Use = {0} to zero-out memory and/or define a student constructor.
student s[0].name = "Jack";
This won't compile. I think you meant to put just s[0].name = "Jack"
The assignment operator = is not defined (by default) for strings. Note that your struct's member type is char whereas a string literal is const char[N], so in reality you're assigning a pointer (due to Array Decay) to a char member. This is a meaningless operation.
Your main does not return a value. Use return EXIT_SUCCESS; on success. This is not strictly required, but I personally believe it's good practice to explicitly return a value.

How to declare a char array by using a variable as its size? [closed]

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 7 years ago.
Improve this question
char* mystrcat2(char* source, char* target) {
int count = strlen(source) + strlen(target) + 1;
char arr[count];
//...
}
I want to create a char array, but VS2013 told me a error, the count should be a constant.I used VS2013 and this is a win32 console application with C++.
if the code like this is OK:
char arr[100];
How to declare a char array with a variable?
recently I'm learning C by reading "The C Programming Language"
You can always use dynamic allocation
char *array;
size_t length;
length = strlen(source) + strlen(target) + 1;
array = malloc(length);
if (array == NULL)
abort_DoNot_Use_array();
/* use `array' here */
free(array); /* don't forget this */
Your exact question was
How to declare a char array with a variable?
Therefore, even though it is often better to use a std::string in C++, I will answer your exact question (under C++ assumption, since you already have a C-answer (malloc/free).
There are no variable sized arrays in C++, for that we have the STL class std::vector. What you need to do is allocate memory dynamically.
Example:
char* mystrcat2(char* source, char* target)
{
char* pChar = new char[strlen(source) + strlen(target) + 1];
// ...
return pChar;
}
When you are finished with the char-pointer returned from this function you must not forget to call
delete[] pChar;
Remark: In C++11 it is typically not recommended to use raw pointers (like we do in this example), because you have automatic resource management via std::unique_ptr (for example).
Being new to C++ I would recommend to use std::string instead of char*. Your code could be something like this.
#include <iostream>
#include <string>
using namespace std;
string mystrcat2(const string& source, const string& target) {
return source + target;
}
int main() {
cout << mystrcat2("Peter", "Kamps");
return 0;
}
g++ allows C99 Variable Length Arrays in C++ as a language extension. But it is not supported in standard C++.
the best options are std::vector or std::string.
Another way of doing this
char * mystrcat2(char * source, char * target) {
std::string result(source);
result += target;
return result.c_str();
}
A C++11 version
char * mystrcat2(char * source, char * target) {
return (to_string(source) + target).c_str();
}

How do I go about editing the variables in a struct array?

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.

how do you add value in runtime to structural arrays (in c++)

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.