I am just getting started on C++ and am working on codeval questions, so if anyones done that, they'll recognize this problem as it's the first on the list. I need to open a file that has 3 columns of space separated integer values. Here is mine, under fizbuz.txt. I need to get the integer values from the file and store them for later use elsewhere in the program.
1 2 10
3 5 15
4 5 20
2 8 12
2 4 10
3 6 18
2 3 11
8 9 10
2 5 8
4 9 25
Now I can open the file just fine, and I've used getline() to read the files just fine using my below code. However, I don't want them in string format, I'd like them as integers. So I looked around and everyone basically says the same notation (file>>int1>>int2...). I've written some code exactly how I've seen it in a few examples, and it does not behave at all like they're telling me it should.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string filename = "fizbuz.txt";
string line;
int d1,d2,len;
int i =0;
int res1[10], res2[10], length[10];
ifstream read (filename.c_str());
if (read.is_open())
{
// while(read>>d1>>d2>>len);
// {
// res1[i] = d1;
// res2[i] = d2;
// length[i] = len;
// i++;
// }
while (!read.eof())
{
read>>d1>>d2>>len;
res1[i] = d1;
res2[i] = d2;
length[i] = len;
}
read.close();
}
else
{
cout << "unable to open file\n";
}
for (int j = 0; j < 10;j++)
{
cout<< res1[j] << " " << res2[j] << " " << length[j] << '\n';
}
}
Both of the while loops perform the same in the output function at the bottom. The last line of fizbuz.txt will be returned to the first elements of res1,res2 and length, and the remaining elements of all 3 are psuedorandom values, presumably from whatever program was using that memory block before. ex output below
4 9 25
32767 32531 32767
-1407116911 4195256 -1405052128
32531 0 32531
0 0 1
0 1 0
-1405052128 807 -1404914400
32531 1 32531
-1405054976 1 -1404915256
32531 0 32531
The first version should work except that you need to remove the ; in the while line.
while (read >> d1 >> d2 >> len);
^
Try this
while (!read.eof())
{
read>>d1>>d2>>len;
res1[i] = d1;
res2[i] = d2;
length[i] = len;
i++;
}
Related
I'm having an issue with my C++ code that involves receiving input from the user and filling an array based on that input. For my function fillArray(), I need a way to read all inputs from one line and to fill an array with those inputs until the user inputs -1 at the end, something other than a positive integer, or exceeds the threshold of 20 elements.
For example, if I input
1 2 3 4 5 6 -1 on one line, I want the displayArray() function to output 1 2 3 4 5 6, or if i write 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21, I want displayArray() to output 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20.
It seems that whenever I input -1 at the end, displayArray() outputs something like
1 2 3 4 5 6 94837 or some arbitrarily big number. If somebody could help me out with this, I'd appreciate it, here's my code:
#include <iostream>
using namespace std;
const int CAPACITY = 20;
void displayArray(int array[], int numElements)
{
for (int i = 0; i < numElements; i++)
cout << array[i] << " ";
cout << endl;
}
void fillArray(int array[], int& numElements)
{
int arrayPosition = 0;
int testArrayPosition = 0;
int testArray[CAPACITY];
bool continueReading = true;
cout << "Enter a list of up to 20 integers or -1 to end the list";
do
{
cin >> valueEntered;
if (valueEntered == -1)
{
continueReading = false;
} else if (valueEntered != -1) {
array[arrayPosition] = valueEntered;
arrayPosition++;
}
} while ((continueReading==true) || (arrayPosition >= CAPACITY));
numElements = (arrayPosition+1);
}
int main()
{
int array[CAPACITY];
int numArrayElements = 0;
fillArray(array, numArrayElements);
displayArray(array, numArrayElements);
cout << "NumArrayElements: " << numArrayElements << endl;
}
The code you posted does not compile. You refer in several places to a variable valueEntered without ever having declared it.
Also, the following construct does not make sense:
if (valueEntered == -1)
{
[...]
}
else if (valueEntered != -1)
{
[...]
Since the condition expression of the second if statement is the exact negation of the condition expression of the first statement, the second if statement is superfluous and can be removed, like this:
if (valueEntered == -1)
{
[...]
}
else
{
[...]
However, since you stated in your question that anything else than a positive integer (not just -1) should cause your program to end, you will want to change that part of your program to the following:
if (valueEntered <= 0)
{
continueReading = false;
}
else
{
array[arrayPosition] = valueEntered;
arrayPosition++;
}
Also, as has already been stated by someone else in the comments section, the line
while ((continueReading==true) || (arrayPosition >= CAPACITY));
should be changed to
while ( continueReading && arrayPosition < CAPACITY )
and the line
numElements = (arrayPosition+1);
should be changed to
numElements = arrayPosition;
I have to write a program that takes a completed sudoku board, saves only the numbers (meaning all the symbols used between the numbers to separate them such as '-', '|' etc cant be saved) into a two-dimensional array.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int input[11] = { 0 };
int sudoku[9][9] = { 0 };
for (int line = 0; line <= 10; line++)
{
cin >> input[line];
}
system("PAUSE");
return 0;
}
This is the only working code I've got so far. I've tried different kinds of for loops to get this done but I can't figure why it doesn't work.
So I wanted to ask, is it even possible save all the numbers of a string into a multi-dimensional array? And if it's not, where is my approach wrong or how could I solve this task?
One example of the input would be:
.5.1.4.|.8.6.9.|.7.2.3
.8.7.2.|.3.4.5.|.6.1.9
.9.6.3.|.2.1.7.|.5.4.8
-------|-------|-------
.6.2.8.|.1.3.4.|.9.5.7
.1.9.7.|.6.5.2.|.8.3.4
.4.3.5.|.7.9.8.|.1.6.2
-------|-------|-------
.2.4.6.|.9.7.1.|.3.8.5
.7.5.1.|.4.8.3.|.2.9.6
.3.8.9.|.5.2.6.|.4.7.1
One approach is to use regular expressions. This way the formatting of the sudoku board can change but your will still be able to parse out the numbers.
The reason I broke it into two for loops was to easily ignore the row that has no numbers in it.
#include <iostream>
#include <regex>
#include <string>
#include <vector>
int main()
{
std::string line;
// this regular expression matches a single digit
std::regex exp("(\\d)");
std::smatch res;
int sudoku[9][9] = {{0}};
int row = 0;
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
// get a line of the board
std::getline(std::cin, line);
// search for the next digit in the line
for (int k = 0; std::regex_search(line, res, exp); ++k)
{
// convert the digit into an integer and store it in the board
sudoku[row][k] = std::stoi(res[0]);
// the rest of the line after the first match becomes the new
// line so that we can search for the next digit
line = res.suffix();
}
row += 1;
}
// ignore every third row that is used to separate the board sections
std::getline(std::cin, line);
}
for (int i = 0; i < 9; ++i)
{
for (int j = 0; j < 9; ++j)
{
std::cout << sudoku[i][j] << " ";
}
std::cout << std::endl;
}
return 0;
}
For your example board, it produces this output:
5 1 4 8 6 9 7 2 3
8 7 2 3 4 5 6 1 9
9 6 3 2 1 7 5 4 8
6 2 8 1 3 4 9 5 7
1 9 7 6 5 2 8 3 4
4 3 5 7 9 8 1 6 2
2 4 6 9 7 1 3 8 5
7 5 1 4 8 3 2 9 6
3 8 9 5 2 6 4 7 1
Suppose I give input to a C++ program as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
C++ code:
int n;
for (int i = 0; i < 15; i++)
{
std::cin >> n;
// use the value of n to make changes
}
In the above code I can read the input sequentially,
i.e. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15.
Is there any way to read input directly (without using extra memory in C++ program) from the input stream in the following order:
5 4 3 2 1 10 9 8 7 6 15 14 13 12 11
First five digits in reverse order 5 4 3 2 1, next five digits in reverse order 10 9 8 7 6, ...
No.
You need to read the data as they flow into the input stream.
In your program then, you can re-order them in any way you like.
As noted in the comments, the best way to do this is to read them in the order they are given and sort them afterwards.
// vector to hold the values
std::vector<int> values;
values.reserve(15); // reserve for better performance
int n;
for (int i = 0; i < 15; i++)
{
std::cin >> n;
values.push_back(n); // add value to back of vector
}
// sort the vector
std::sort(values.begin(), values.end());
// use the values in ascending order...
for (int i = 0; i < 15; i++) {
std::cout << values[i];
}
Yes this is possible ,but it increase the running time complexity of the code .
First you can make the outer loop for how many series it insert , in the above test case its 3.
Secondly you can make a inner loop which adds the number .
I am not sure the code is running but the logic helps you .
I am implementing the psuedo code using stack !
int n=5;
for(int count = 1 ; count <= 3 ;count++)
{
for(int i=n ; i > n-5 ; i++)
{
push_on_stack(i);
}
n=n+5;
}
You need to wrap your taking input in some functionality that reorders the values for you. You might be able to do so outside the program, i.e., pipe the input stream through another program that reorders the values. Then your code might already work as you have it now.
Or you do this wrapping in your program. For example using a custom stream-like class that buffers the values in between.
There's no way to get this done without using extra memory to buffer the values you don't yet need.
Example:
#include <iostream>
#include <stack>
struct reader {
std::stack<int> data;
reader& operator>>(int & i) {
if (data.empty()) {
while (data.size() < 5) {
data.push(0);
std::cin >> data.top();
}
}
i = data.top();
data.pop();
return *this;
}
explicit operator bool() const { return bool(std::cin); }
};
int main () {
reader r;
int i;
while (r >> i) {
std::cout << i << std::endl;
}
}
Example output:
$ g++ tt.cc -std=c++11 && echo "1 2 3 4 5 6 7 8 9 10" | ./a.out
5
4
3
2
1
10
9
8
7
6
A more straight forward approach would probably be something like this:
#include <iostream>
#include <vector>
int main () {
std::vector<int> buffer;
for (int i; std::cin >> i; ) {
buffer.push_back(i);
if (buffer.size() == 5) {
// do something with buffer
//std::vector<int> reversed(buffer.rbegin(), buffer.rend());
while (!buffer.empty()) {
std::cout << buffer.back() << "\n";
buffer.pop_back();
}
}
}
}
I have hit a brick wall trying to format one of my files. I have a file that I have formatted to look like this:
0 1 2 3 4 5
0.047224 0.184679 -0.039316 -0.008939 -0.042705 -0.014458
-0.032791 -0.039254 0.075326 -0.000667 -0.002406 -0.010696
-0.020048 -0.008680 -0.000918 0.302428 -0.127547 -0.049475
...
6 7 8 9 10 11
[numbers as above]
12 13 14 15 16 17
[numbers as above]
...
Each block of numbers has exactly the same number of lines. What I am trying to do is basically move every block (including the headers) to the right of the first block so in the end my output file would look like this:
0 1 2 3 4 5 6 7 8 9 10 11 ...
0.047224 0.184679 -0.039316 -0.008939 -0.042705 -0.014458 [numbers] ...
-0.032791 -0.039254 0.075326 -0.000667 -0.002406 -0.010696 [numbers] ...
-0.020048 -0.008680 -0.000918 0.302428 -0.127547 -0.049475 [numbers] ...
...
So in the end I should basically get a nxn matrix (only considering the numbers). I already have a python/bash hybrid script that can format this file
exactly like this BUT I've switched the running of my code from Linux to Windows and hence cannot use the bash part of the script anymore (since my code has to be compliant will all versions of Windows). To be honest I have no idea how to do it so any help would be appreciated!
Here's what I tried until now (it's completely wrong I know but maybe I can build on it...):
void finalFormatFile()
{
ifstream finalFormat;
ofstream finalFile;
string fileLine = "";
stringstream newLine;
finalFormat.open("xxx.txt");
finalFile.open("yyy.txt");
int countLines = 0;
while (!finalFormat.eof())
{
countLines++;
if (countLines % (nAtoms*3) == 0)
{
getline(finalFormat, fileLine);
newLine << fileLine;
finalFile << newLine.str() << endl;
}
else getline(finalFormat, fileLine);
}
finalFormat.close();
finalFile.close();
}
For such a task, I would do it the simple way. As we already know the number of lines and we know the pattern, I would simply keep a vector of strings (one entry per line of the final file) that I would update as I'm parsing the input file. Once it's done, I would iterate through my strings to print them into the final file. Here is a code that's doing it :
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
int main(int argc, char * argv[])
{
int n = 6; // n = 3 * nAtoms
std::ifstream in("test.txt");
std::ofstream out("test_out.txt");
std::vector<std::string> lines(n + 1);
std::string line("");
int cnt = 0;
// Reading the input file
while(getline(in, line))
{
lines[cnt] = lines[cnt] + " " + line;
cnt = (cnt + 1) % (n + 1);
}
// Writing the output file
for(unsigned int i = 0; i < lines.size(); i ++)
{
out << lines[i] << std::endl;
}
in.close();
out.close();
return 0;
}
Note that, depending of the structure of your input/ouput files, you might want to adjust the line lines[cnt] = lines[cnt] + " " + line in order to separate the columns with the right delimiter.
2
1 3
2 4 8 13
3 5 6 13
4
4
8
3 7 9 10 13
8 10 11
8 9 11 12
9 10
10 15
3 4 8 14
13
12 16
15 17 18
16
18 16
I want to read this these values from file into two dimensional STL vector. Note that the size of inner vector is not uniform and not known in adance so I need to detect '\n'. So far I have been unnsuccessful. My code is as follows. Please help. What is wrong?
int main()
{
ifstream Lin("A.txt");
double d;
vector<vector<double> > A;
vector<double> dummy;
if (Lin.is_open()){
while (Lin >> d) {
if (Lin.peek() == '\n'){
A.push_back(dummy);
dummy.clear();
}else{
dummy.push_back(d);
}
}
Lin.close();
}
...
return 0;
}
When I iterate over the vector using the following code
, it reveals what is stored:
for(int i = 0; i< A.size(); i++){
for(int j = 0; j< A[i].size() ; j++){
cout << A[i][j] << " ";
}
cout << endl;
}
1
2 4 8
3 5 6
3 7 9 10
8 10
8 9 11
9
10
3 4 8
12
15 17
18
The intended output is same as the way it is stored in the file
Make sure that there is no empty space after the last integer in each line in the data file.
In the code currently you are not adding the last integer to the dummy vector. Modify it like this:
while (Lin >> d)
{
dummy.push_back(d); // Add the number first
if (Lin.peek() == '\n') // Then check if it is end of line
{
A.push_back(dummy);
dummy.clear();
}
}
Less is more. This replaces your entire loop. Note: You don't need to check is_open or call close for this to work safely.
for(std::string s; std::getline(Lin, s);)
{
A.emplace_back(std::istream_iterator<double>(std::istringstream(s)),
std::istream_iterator<double>());
}
Consider using getline.
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main() {
std::string line;
std::vector<std::vector<double> > v;
while(std::getline(cin, line)) {
std::stringstream ss(line);
double value;
std::vector<double> numbers;
while(ss >> value) {
numbers.push_back(value);
std::cout << value << std::endl;
}
v.push_back(numbers);
}
return 0;
}
There could be other whitespace characters after the number at the end of line, other than \n. Like spaces:
1234 445 445 \n
^^^^
So your approach is not safe. Better would be to read entire line (getline) to some string, then construct istringstream on this string containing line, then just parse this istringstream to your vector for one line.
Like this:
for (string line; getline(filein, line); ) {
vector<double> dd;
istringstream is(line);
for (double d; is >> d; )
dd.push_back(d);
if (not dd.empty())
A.push_back(dd);
}