Store multiple arrays based on user input - c++

I'm trying to create a function where it allows the user to type in multiple amounts of integers, so if the user wanted to have 3 different storages that hold different integers, the input would look something like this:
5
97 12 31 2 1 //let's say this is held in variable "a"
1 3 284 3 8 // "b"
2 3 482 3 4 // "c"
2 3 4 2 3 // "d"
99 0 2 3 42 // "e"
Since we don't know what number the user will input every time, I'm not sure how to create a dynamically allocated array that will create an x amount of arrays every time.. I want to be able to access each index of a, b, c, d, e or however many arrays there are.
So far, this is what I have, but I'm having trouble creating the arrays since it's unpredictable. I'm purposely not using vectors because I don't really get how pointers work so I'm trying to play around with it.
int* x;
int length, numbers;
cin >> length;
x = new int[length]
for (int i=0;i<length;i++)
{
std::getline(std::cin, numbers); //this didn't work for me
x[i] = numbers
}
If anything seems unclear, please let me know! Thank you!

It doesn't get the first line. It gets 1 integer at a time and since you have 5 integers per line and you entered 5 in the first line you end up getting only the numbers in the first line. x in your code is an array of integers and it needs to have enough place for all your integers which in this case is 25. If 5 integer per line is guaranteed then you can assume allocating 5 * length integer-long place will work. You will also need an inner for loop. 1 for to loop through lines and another one to loop through every integer on a line.

I would suggest using cin like so:
int d;
while(cin){
cin >> d;
// Do something with d
if(cin.peek() == '\n'){
// Create a new row in your dynamic array
}
}
This will grab each digit up to the space.
Another way to achieve this is by using strings with getline() in conjunction with string.empty() to get each line, then using strtok to split the line up into tokens. Although getline only works on strings, strtok will split the string up into tokens, which you can then cast to an int (or use atoi).
To store these tokens you will want to use a vector, since they are dynamic by nature and can easily be resized to fit any need. I would see this discussion on multi-dimensional vectors.

Related

C++: How can I perform an operation on every number inside a text file?

If I have a text file which only has numbers inside. Such as:
1
2
3
4
5
6
How can I, for example, multiply each number by two and get the result of each individual operation as output to my screen? Would I have to set each number to a variable?
The best solution to your problem is to follow these steps:
Open a file, and create an int variable ( for instance a)
In Do...while loop take number from a file like this
Filehandler >> a;
multiply the a like this
a = a * 2;
or do whatever you want with it.
Print an value
cout << a;
till you get EOF
Of course there is another possibility like storing each value in array and then multiplying it. It depends on you what you will choose.
Do you know for Loops for example.
you can read the the numbers and store them in an array and use a for loop to multiply or div or whatever and print that .

How can I read from the same input file multiple times from different points within the file using sentinel values (-1) in c++?

I have a task where I have to read different sections of an input file(.txt) of integers in c++. The file contains an unknown number of positive integers, each separated by white-space with several sentinel values of -1 placed randomly in the list to "break-up" the list into sections and another -1 at the end of the file.
Here is a sample of my input file(.txt):
3 54 35 4 9 16 -1 14 57 32 4 6 8 41 2 -1 5 6 54 21 3 -1
Here is what I've attempted so far:
int data[20],
index = 0;
ifstream fin;
fin.open("data_file.txt");
while (index < 20 && data[index] != -1 && fin >> data[index])
{
cout << data[index] << endl;
index++;
}
I can't get this to read past the first SV even if I repeat this while loop. It always just starts at the beginning of the file.
How do I read again STARTING AFTER the first SV to the second SV? The only methods I know involve reading a file from beginning to end. How do I read seperate sections?
Thanks in advance for any help,
Cheers
It sounds like you just want to group information from the file. I will not provide code since you didn't, but I may help you with the logic:
Create a file object, 2d vector, and a string
Read from the file object to the string
if the value is equal to "-1", then add a new row. Else, add a new column
The result will be a 2d vector with the rows being each group, and the columns being each positive number in that group.

Reading from a file with multiple columns of integers and putting them into arrays

I am creating a command-line minesweeper game which has a save and continue capability. My code generates a file called "save.txt" which stores the position of the mines and the cells that the player has opened. It is separated into two columns delimited by a space where the left column represents the row of the cell and the right column represents the column of the cell in the matrix generated by my code. The following is the contents of save.txt after a sample run:
3 7
3 9
5 7
6 7
8 4
Mine end
2 9
1 10
3 5
1 1
Cell open end
You may have noticed Mine end and Cell open end. These two basically separate the numbers into two groups where the first one is for the position of the mines and the latter is for the position of the cells opened by the player. I have created a code which generates an array for each column provided that the text file contains integers:
int arrayRow[9];
int arrayCol[9];
ifstream infile("save.txt");
int a, b;
while(infile >> a >> b){
for(int i = 0; i < 9; i++){
arrayRow[i] = a;
arrayCol[i] = b;
}
}
As you can see, this won't quite work with my text file since it contains non-integer text. Basically, I want to create four arrays: mineRow, mineCol, openedRow, and openedCol as per described by the first paragraph.
Aside from parsing the string yourself and doing string operations, you can probably redefine the file format to have a header. Then you can parse the once and keep everything in numbers. Namely:
Let the Header be the first two rows
Row 1 = mineRowLen mineColLen
Row 2 = openedRowLen openedColLen
Row 3...N = data
save.txt:
40 30
20 10
// rest of the entries
Then you just read 40 for the mineRow, 30 for mineCol, 20 for openedRow, 10 for openedCol since you know their lengths. This will be potentially harder to debug, but would allow you to hide the save state better to disallow easy modification of it.
You can read the file line by line.
If the line matches "Mine end" or "Cell open end", continue;
Else, split the line by space (" "), and fill the array.

C++ check if the last thing read from file was a number

this is quite a primitive problem, so I guess the solution shouldn't be hard, but I didn't find a way how to do it simply, neither have I summarized it to actually find it in the internet.So going to the question, I have a file of information like this:
1988 Godfather 3 33 42
1991 Dance with Wolves 3 35 43
1992 Silence of the lambs 3 33 44
And I have a requirement to put all the information in a data structure, so lets say it will be int year, string name and three more int types for numbers. But how do I know if the next thing I read is a number or not? I never know how long is the word.Thank you in advance for anyone who took their time with such a primitive problem. :)
EDIT: Don't consider movies with numbers in their title.
You're going to have some major issues when you go to try to parse other movies, like, Free Willy 2.
You might try instead to treat it as a std::stringstream and rely on the last three chunks being the data you're looking for rather than generalizing with a Regular Expression.
your best bet would be to use C++ regex
That would give you a more fine grained control over what you want to parse.
examples:
year -> \d{4}
word -> \w+
number->\d+
If you do not have control over the file format, you may want to do something along these lines (pseudo-process):
1) read in the line from the file
2) reverse the order of the "words" in the file
3) read in the 3 ints first
4) read in the rest of the stream as a string
4) reverse the "words" in the new string
5) read in the year
6) the remainder will be the movie title
Read every field as a string and then convert the appropriate string to integers.
1)initially
1983
GodFather
3
33
45
are all strings and stored in a vector of strings (vector<string>).
2)Then 1983(1st string is converted to integer using atoi) and last three strings are also converted to integers. Rest of the strings constitute the movie_name
Following code has been written under the assumption that input file has already been validated for the format.
// open the input file for reading
ifstream ifile(argv[1]);
string input_str;
//Read each line
while(getline(ifile,input_str)) {
stringstream sstr(input_str);
vector<string> strs;
string str;
while(sstr>>str)
strs.push_back(str);
//use the vector of strings to initialize the variables
// year, movie name and last three integers
unsigned int num_of_strs = strs.size();
//first string is year
int year = atoi(strs[0].c_str());
//last three strings are numbers
int one_num = atoi(strs[num_of_strs-3].c_str());
int two_num = atoi(strs[num_of_strs-2].c_str());
int three_num = atoi(strs[num_of_strs-1].c_str());
//rest correspond to movie name
string movie_name("");
//append the strings to form the movie_name
for(unsigned int i=1;i<num_of_strs-4;i++)
movie_name+=(strs[i]+string(" "));
movie_name+=strs[i];
IMHO Changing delimiters in the file from space to some other character like , or ; or : , will simplify the parsing significantly.
For example , if later on the data specifications change and instead of only last three , either last three or last four can be integers then the code above will need major refactoring.

forloop lines of arrays

int lineInputs = 0;
cin >> lineInputs;
int whatever = 0;
char* myArray = new char[arrayElements*lineInputs];
int j =0;
for(int i = 0; i < lineInputs; i++)
{
cin >> whatever;
for(j; j<total; j+=39)
{
for(int nom=0; j<arrayElements; nom++)
{
cin >> myArray[j];
}
}
}
In my forloop say i have lineInputs = 4 and total = 156
Meaning 4 times we do this, we want to insert 156 chars into my array. But we want to make it so that every 40 characters we continue entering the array.
Bsically we need to insert this input into the array but i feel like my forloops are messed up. This will be the input
4
1
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
2
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
3
HHTTTHHTTTHTHHTHHTTHTTTHHHTHTTHTTHTTTHTH
4
HTHTHHHTHHHTHTHHHHTTTHTTTTTHHTTTTHTHHHHT
The first line 4 meaning 4 of these 40 character lines. And the number above the character lines just signifying line 1 2 3 4 ect.
How can i attempt this right?
So the array would basically look like this.
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTHHTTTHHTTTHTHHTHHTTHTTTHHHTHTTHTTHTTTHTHHTHTHHHTHHHTHTHHHHTTTHTTTTTHHTTTTHTHHHHT
You are making the same fundamental mistake you made in your other question, which is to fail to treat the input array correctly. You are repeatedly reading into the first 40 characters of myArray. What you need to do is read the first line into the first 40 characters, the second line into characters 40 to 79, etc.
Better yet, make it a two dimensional array so that you don't have to muck around with computing the indices.
Even better, make it an array of std::string rather than an array of char.