how to import text file into structs C++ - c++

I'm trying to import data from a text file into structs for use as i don't really want to import them into seperate arrays.
I keep getting "error: expected primary-expression before '[' token" on each getline, i'm terrible at C++ and basically using what C skills i have to try and make sense of this. What am i doing wrong?
#include <stdio.h>
#include<fstream>
#include <cstdlib>
#include <iostream>
#include "Ladybird.h"
using namespace std;
typedef struct managerImport{
int gridSizeA;
int gridSizeB;
int aphidCount;
int aphidPos;
int ladyCount;
int ladyPos;
struct managerImport *next;
};
void importData(managerImport[]){
ifstream manager;
manager.open("Manager.txt");
if (!manager.fail()){
//loops the 2d array
for (int i = 0; i < 1; i++)
{
getline(manager, managerImport[i].gridSizeA, managerImport[i].gridSizeB);
}
//loop the lady bird count
for (int i = 1; i < 2; i++)
{
getline(manager, managerImport[i].ladyCount);
}
//loops the lady bird coordinates
for (int i = 2; i < 10; i++)
{
getline(manager, managerImport[i].ladyPos);
}
for (int i = 10; i < 11; i++)
{
getline(manager, managerImport[i].aphidCount);
}
//loops the lady bird coordinates
for (int i = 11; i < 19; i++)
{
getline(manager, managerImport[i].aphidPos);
}
}
manager.close();
}
int main() {
//importing the manager text file
importData;
}

Did you name the argument in the function?
void importData(managerImport[]) just says you have a function importData that takes an array of type managerImport (your struct).
Edited for clarification:
Imagine I write this code:
int increment(int) { return int+1; }
What I've done is hand the compiler a function that takes an argument "int". Is "int" a type or the name of my argument? This obviously won't compile since the argument has to have both a type and a name (so even if I want want to name my argument "int" (not advised), I still need to supply a type which says what "int" actually is (type-wise). Is it a long, a string, an unsigned char? Assuming I meant to actually accept an int, add 1, and return the incremented value (an int), this is what I should have written:
int increment(int i) { return i+1; }
So, in your case, you have:
void importData(managerImport[]) { ... }
Obviously, you're meaning to accept an array of managerImport, but you haven't given that array a name. Try this:
void importData(managerImport foo[]) { .. }
Also, unless you really need a c-array, you might try using a vector or an C++ array (std::array).

The function getline does not translate text into integers. It simply copies text without translations.
for (int i = 0; i < 1; i++)
{
getline(manager, managerImport[i].gridSizeA, managerImport[i].gridSizeB);
}
Your getline function call translates to getline(stream, int, int);.
You will need to either use:
manager >> managerImport[i].gridSizeA >> managerImport[i].gridSizeB;
or read in as string and parse out of the string.

Related

Modification of counting sort

The Counting sort below sorts elements based on their ASCII value.
The code below works fine but I want to do some I/O modification. The code doesn't take custom input.
I tried to do some changes but getting undefined behavior. My first doubt is why I'm getting undefined behavior. secondly, Please provide me with the code which will make the below code run as expected. The comment portion is what I tried by myself.I want it to take input from user.
#include<bits/stdc++.h>
#include<string.h>
using namespace std;
#define RANGE 255
void countSort(char arr[]) //void countSort(char arr[],int n)
{
char output[strlen(arr)]; //char output[n];
int count[RANGE + 1], i;
memset(count, 0, sizeof(count));
for(i = 0; arr[i]; i++) {
count[arr[i]]++;
}
for (i = 1; i <= RANGE; ++i) {
count[i] += count[i-1];
}
for (i = 0; arr[i]; ++i) {
output[count[arr[i]]-1] = arr[i];
--count[arr[i]];
}
for (i = 0; arr[i]; ++i) {
arr[i] = output[i];
}
}
// Driver code
int main()
{
char arr[] = "geeksforgeeks";
countSort(arr);
cout<< "Sorted character array is "<<arr;
/*
int n;
cin>>n;
char arr[n];
for(int i=0;i<n;i++) {
cin>>arr[i];
}
countSort(arr,n);
for(int i=0;i<n;i++) {
cout<<endl<<arr[i];
}
*/
return 0;
}
So the OP asked, how to take an input from the user and sort this. And not a predefined string in a given char array.
I will give the answer. But the question is tagged with C++, and I will convert it to C++.
By the way. The code in the question is a one to one copy from GeeksforGeeks and tries to code the so called Counting Sort algorithm in C++ that is described here.
Since the code is taken from GeeksforGeeks I unfortunately need to blame user "rathbhupendra" for really bad C++ code. I am truly sorry.
The code is using:
C-Style arrays
Variable Length Arrays (Compiler extension. Not C++ compliant)
strlen
memset
#include<bits/stdc++.h> and #include<string.h>
using namespace std
unusal end conditions in for loops for(i = 0; arr[i]; ++i)
char arrays instead of std::strings
a Macro to define an array size (#define RANGE 255)
So, nothing C++.
And now, the answer.
You need to read the string from the user in a variable of type std::string with the function std::getline.
A std::string can be used like a character array. No difference.
Please see the C++ solution:
EDIT
Edited on the comments of MichaelDorgan
#include <iostream>
#include <string>
#include <vector>
constexpr size_t AsciiRange = 256;
// Convert signed char to unsigned size_t type.
inline size_t char2sizet(char c) { return static_cast<size_t>(static_cast<unsigned char>(c)); }
void countSort(std::string& stringToSort)
{
std::vector<size_t> count(AsciiRange, 0U);
size_t i { 0U };
for (i = 0U; i < stringToSort.size(); i++) {
count[char2sizet(stringToSort[i])]++;
}
for (i = 1U; i < AsciiRange; ++i) {
count[i] += count[i - 1U];
}
std::string output(stringToSort);
for (i = 0U; i < stringToSort.size(); ++i) {
output[count[char2sizet(stringToSort[i])] - 1U] = stringToSort[i];
--count[char2sizet(stringToSort[i])];
}
stringToSort = output;
}
int main()
{
std::cout << "\nPlease enter a string:\n\n";
// Get the string from the user
std::string inputString{};
getline(std::cin, inputString);
// Sort it by characters
countSort(inputString);
// Show result
std::cout << "\n\n\nString sorted by characters is:\n\n" << inputString << '\n';
return 0;
}
Hope this helps . . .
I geuss by 'getting undefined behavior' you meant segmentation fault which sometimes occured. The problem lies in this line
for(i = 0; arr[i]; i++)
instead you should write
for(i = 0; i < n; i++)
You can check that in the first case at the end of each loop arr[i] is sometimes some weird character(this character doesn't belong to the input string) and count[arr[i]] for this char returns negative number which produce segmentation fault here
output[count[arr[i]]-1] = arr[i];

Invoking function with paremeters, one of which is an array of structures in C++?

I have a program where I have a function that sorts elements of an array of structures by their key field. However, when I invoke the function Insertion(a[],7) - I pass the array and its size, the compiler gives an error expected primary expression before ']' token. I would like to ask what am I doing wrong?
#include <iostream>
using namespace std;
struct CElem
{
int key;
};
CElem a[7];
void Insertion(CElem m[],int n)
{
CElem x;
int i;
int j;
for (i = 0; i < n; i++)
{
x = m[i];
j = i-1;
while (j >= 0 && x.key < m[j].key)
m[j+1] = m[j--];
m[j+1] = x;
}
}
int main()
{
a[0].key=32;
a[1].key=45;
a[2].key=128;
a[3].key=4;
a[4].key=-9;
a[5].key=77;
a[6].key=-7;
Insertion(a[],7);
return 0;
}
you only need to pass the pointer to the start of the array:
Insertion(a, 7);
Your parameter m of the method Insertion is of type CElem*. The variable a is of type CElem* too so you are supposed to give the method just a, like Insertion(a,7);.

Whats wrong with this one? C++ Array Pointer

It says:
[Error] invalid conversion from 'int*' to 'int' [-fpermissive] on line 9 col 5.
What was asked of me to do:
Make a program that would accept array of 10 integers and determine the highest and the lowest integers from the set of integers. Use pointer variables for the highest and lowest integer.
what i did:
#include<iostream>
using namespace std;
int main()
{
int kre_arr[10];
int *kre_p;
for(int k = 0; k<=10; k++)
{
kre_p[k] = &kre_arr[k];
}
int j,temp;
cout<<"Enter 10 Integers: ";
for (*kre_p=0; *kre_p < 10; *kre_p++)
{
cin>>kre_arr[*kre_p];
}
for(*kre_p=0;*kre_p<=10;*kre_p++)
{
for(j=*kre_p+1;j<=10;j++)
{
if(kre_arr[*kre_p] > kre_arr[j])
{
temp = kre_arr[*kre_p];
kre_arr[*kre_p] = kre_arr[j];
kre_arr[j] = temp;
}
}
}
for(*kre_p=0;*kre_p<=9;*kre_p++)
{
cout<<endl<<kre_arr[*kre_p];
}
}
code i did before adding pointer i dont seem to understand pointer that much.
#include<iostream>
using namespace std;
int main()
{
int kre_arr[10];
int *kre_p;
int i,j,temp;
cout<<"Enter 10 Integers: ";
for (int i=0; i < 10; i++)
{
cin>>kre_arr[i];
}
for(i=0;i<=10;i++)
{
for(j=i+1;j<=10;j++)
{
if(kre_arr[i] > kre_arr[j])
{
temp = kre_arr[i];
kre_arr[i] = kre_arr[j];
kre_arr[j] = temp;
}
}
}
for(i=0;i<=9;i++)
{
cout<<endl<<kre_arr[i];
}
}
Looking at what you are asked to do I think you just have to determine the highest and lowest int in the array and point to. You sort the array thats slower.
I think it should look like that:
#include<iostream>
using namespace std;
int main()
{
int kre_arr[10];
int *low;
int *high;
cout<<"Enter 10 Integers: ";
for (int i=0; i < 10; i++)
{
cin>>kre_arr[i];
}
//determine the lowest
low=&kre_arr[0];
for(int i=1;i<10;i++)
{
if(kre_arr[i] < *low)
{
low=&kre_arr[i];
}
}
//determine the highest
high=&kre_arr[0];
for(int i=1;i<10;i++)
{
if(kre_arr[i] > *high)
{
high=&kre_arr[i];
}
}
cout<<"lowest: "<<*low<<"\nhighest: "<<*high;
}
kre_p[k] = &kre_arr[k];
kre_arr is array.
kre_arr[k] is integer.
&kre_arr[k] is integer address ( similar int*)
kre_p is pointer.
kre_p[k] is integer.
So, as a result, you cannot pass directly int* to int.
I guess you want kre_p+k = &kre_arr[k]
Given the state of your code, I fear for your life... So, for your overal survival, and of course in the hopes that you will learn something:
Never use 'using namespace std'. It's bad form.
You are not allocating memory for your array of pointers (kre_p). That will cause your program to crash for sure.
You don't actually need an array of pointers. Your array elements can be conveniently referred to by their offset in the array.
You are doing what appears to be a bubblesort to find the lowest and highest value. That's incredibly inefficient, and completely unnecessary.
C++ can be such a nice language. It bothers me when teachers seem to think they should be teaching it in a form that's as ugly as possible. Consider:
#include <algorithm>
#include <array>
#include <iostream>
int main () {
std::cout << "Enter 10 Integers: ";
std::array<int, 10> kre_arr;
for (auto &Val : kre_arr)
std::cin >> Val;
const int Low = *std::min_element (kre_arr.begin (), kre_arr.end ());
const int High = *std::max_element (kre_arr.begin (), kre_arr.end ());
// The assignment calls for pointers, so let's not disappoint.
const int *LowPtr = &Low;
const int *HighPtr = &High;
}

Vector as an argument in function

I have a code like this:
Forgive me Polish names for stuff, I hope it isn't a problem. I can change them if you wanna.
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
//a few unimportant functions
void zamianaNaDziesietny(int podstawa, int liczba, int reszta[])
{
vector < int > cyfra;
cout <<"\n";
for(int a = reszta.size(); a > 0; a--)
{
cyfra.push_back(reszta[a - 1] * pow(podstawa, a - 1));
}
for(int a = 1; a < cyfra.size(); a++)
{
cyfra[0] += cyfra[a];
}
cout << cyfra[0];
}
void zamianaNaDziesietny(int podstawa, int liczba, int reszta[])
{
vector < int > cyfra;
cout <<"\n";
for(int a = reszta.size(); a > 0; a--) //request for member 'size' in 'reszta', which is of non-class type 'int*'
{
cyfra.push_back(reszta[a - 1] * pow(podstawa, a - 1));
}
for(int a = 1; a < cyfra.size(); a++)
{
cyfra[0] += cyfra[a];
}
cout << cyfra[0];
}
//another unimportant part of code
int main()
{
//unimportant stuff
zamianaZDziesietnego(podstawa, liczba);
zamianaNaDziesietny(podstawa, liczba, reszta);
return 0;
}
I dunno how to use vector 'reszta' as an argument in function "zamiananaDziesietny".
What should I type to let this program compile?
I'm getting 2 errors:
One of them is:
'reszta' was not declared in this scope
It's an array... Oh well, vector is a kind of array... I think... I'm noob so I can always be wrong.
I can work on this vector in main, adding "cout << reszta[0];" (just to write on the screen an element of this vector) in main, just between inductions of those two functions worked well. But I think this problem could be solved by setting this vector in main and then it will be as an argument in zamianaZDziesietnego() function too, but...
I dunno how to use a vector as an argument in function.
The second error I'm getting is:
request for member 'size' in 'reszta', which is of non-class type 'int*'
It's in the 32nd line.
So this is my problem.
I have tried typing this argument in a few different ways.
When I tried with:
void zamianaNaDziesietny(int podstawa, int liczba, vector reszta[])
The second error changed to:
request for member 'size' in 'reszta', which is of pointer type 'std::vector*' (maybe you meant to use '->' ?)|
And also got a new error a few lines below:
no match for 'operator*' in '*(reszta + ((((sizetype)a) + -1u) * 12u)) * pow((double)podstawa, (double)(a + -1))'|
Well, I am very a big noob and I dunno how to solve this. Could anyone help?
Btw, if anyone was interested - I'm making a program that converts binear counts to decimal and vice versa.
Just declare the argument like this:
void zamianaNaDziesietny(int podstawa, int liczba, std::vector<int> reszta)
{
vector < int > cyfra;
cout <<"\n";
for(int a = reszta.size(); a > 0; a--)
{
cyfra.push_back(reszta[a - 1] * pow(podstawa, a - 1));
}
for(int a = 1; a < cyfra.size(); a++)
{
cyfra[0] += cyfra[a];
}
cout << cyfra[0];
}
Or better still, pass the vector by reference to avoid it being copied:
void zamianaNaDziesietny(int podstawa, int liczba, std::vector<int>& reszta)
{
vector < int > cyfra;
cout <<"\n";
for(int a = reszta.size(); a > 0; a--)
{
cyfra.push_back(reszta[a - 1] * pow(podstawa, a - 1));
}
for(int a = 1; a < cyfra.size(); a++)
{
cyfra[0] += cyfra[a];
}
cout << cyfra[0];
}
What you have done is use an int array (int reszta[]) as the argument rather than a vector - they are different types.
Vectors are different than arrays, as vectors are classes and can have methods called upon them (ex. .size(). Arrays are from c which are really just pointers in memory. Passing in the reference as stated would be the best way to pass in the vector, but make sure to be careful about modification.

How to pass two dimensions array to a function and how to call it

I've tried many time to pass the array to a function then do some calculation such as getting the total of the columns, the problem is I don't know how to call the result form the function, usually I get errors.
this is just one code I'm trying to solve it from yesterday :
#include <iostream>
using namespace std;
//prototype
int get_total(int whatever[][2], int row);
int main ()
{
const int row=2;
const int col=3;
int marks[row][col];
// this is prompt the user to input the values
for (int i=0; i<row;i++)
{
for (int p=0; p<col; p++)
{
cin >> marks[i][p];
}
cout << endl;
}
// this is just display what the user input as a table
for (int x=0; x< row ; x++)
{
for (int y=0; y<col ; y++)
{
cout << marks[x][y] << " ";
}
cout << endl;
}
int sum;
// this is the most important thing I want to know,
// how to call the function :(
sum=get_total(marks,row);
return 0;
}
// to get the total of each columns
const int row=3;
// not sure if the declaration is correct or not :(
int get_total(int whatever[][2], int row)
{
for (int i=0; i < 2; i++)
{
for (int p=0; p < 3; p++)
int total=0;
//this line is completly wrong, How can I calculate the total of columns?
total+=get_total[2][p];
}
// do we write return total ?
// I'm not sure because we need the total for each column
return total;
}
sorry for the mess, and I appreciate any help to explain passing the multidimensions arry to a function as parameter and how to call the function>
Arrays decay to pointers when calling functions.
You can do 2 things:
Pass the number of lines and columns as arguments to the function.
Use std::vector instead. I suggest you take a look at it, it'll do the trick and you'll learn something new and very useful.
Also, your function should do this:
int get_total(int** whatever)
{
//total is 0 at the beginning
int total=0;
for (int i=0; i < 2; i++)
{
for (int p=0; p < 3; p++)
//go through each element and add it to the total
total+=whatever[i][p];
}
return total;
}
This will return the total for the whole matrix, I'm assuming that's what you mean by getting the total of the columns
int marks[row][col]
This means that marks has type int[2][3].
int get_total(int whatever[][2], int row);
You've however declared get_total to accept an int(*)[2]. int[2][3] can decay to int(*)[3] but that is not compatible with int(*)[2], hence why you can't pass marks to get_total. You can instead declare get_total to accept an int(*)[3]:
int get_total(int whatever[][3], int row);
// equivalent to:
int get_total(int (*whatever)[3], int row);
If you instead decide to declare get_total to accept an int** or an int*, then you can't legally pass marks to it in the former case, and you can't legally iterate over the whole multidimensional array in the latter. Consider not using arrays, it's simpler this way.