I am a java/C# developer and i am trying to write a C or C++ code to read data from a text file. this is very easily done in java and c# but not in c or c++.
the textfile i am reading looks like this:
a,b,c,d,e
1,0,1,1,0
0,1,1,0,0
0,0,0,1,1
i need to store the values in 2 arrays.
the 1st one is a 1D char array which will contain: a b c d e
the 2nd one is a 2D bool array which will contain:
1 0 1 1 0
0 1 1 0 0
0 0 0 1 1
how can i do this?
I suggest you at least make an attempt at what you are trying to do, to help you get started, here is a basic read out of the example data you provided. This example should be simple enough to allow you to expand it to meet other data sets.
#include <iostream>
#include <fstream>
int main() {
const int n_letters = 5;
const int n_columns = 5;
const int n_rows = 3;
char letters[n_letters];
bool booleans[n_rows][n_columns];
std::ifstream stream("myfile.txt");
if (stream) {
for (int i = 0; i < n_letters; ++i) {
stream >> letters[i];
std::cout << letters[i] << ',';
}
std::cout << '\n';
for (int i = 0; i < n_rows; ++i) {
for (int j = 0; j < n_columns; ++j) {
stream >> booleans[i][j];
std::cout << booleans[i][j] << ',';
}
std::cout << '\n';
}
}
return 0;
}
Reads the following text:
a b c d e
1 0 1 1 0
0 1 1 0 0
0 0 0 1 1
And outputs:
a,b,c,d,e
1,0,1,1,0
0,1,1,0,0
0,0,0,1,1
A first comment: when parsing a file, it's often useful to read
the file line by line, and then parse each line, using
std::istringstream, or boost::regex, or whatever other technique
you please. I like boost::regex, because it immediately
indicates if there is a syntax error, but carefully designed,
istream can as well.
The first thing, in any case, is to specify more precisely the
formats: Is there always just one letter? Are the numbers always
Just 0 and 1? Are there always exactly five values per line?
Until we know that, it's rather difficult to say more.
Related
My code prints 1 at every position except the first column. I want it to print 1 at certain specific places (r, c) where r is the row and c is the column. Also, can anybody tell me how do I initialize the 2-D array with 0 at every index?
I have tried to reset the values of r and c to zero but nothing changes.
int main()
{
int T;
cin>>T;
while(T--)
{
vector <long long int>R;
vector <long long int>C;
long long int N, M, K, r, c, i, j, k; // N -> rows, M -> columns
cin>>N>>M>>K;
long long int arr[N][M];
cout<<K<<endl;
for(i=0; i<N; i++)
{
for(j=0; j<M; j++)
{
arr[i][j] = 0;
}
}
for(k=0; k<K; k++)
{
cin>>r>>c;
arr[r][c] = 2;
r = 0; c = 0;
}
for(i=0; i<N; i++)
{
for(j=0; j<M; j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
}
return 0;
}
Input:
1 4 4 9 1 4 2 1 2 2 2 3 3 1 3 3 4 1 4 2 4 3
Some remarks:
Firstly, C-Style Array sizes must be known at compile time for standard C++, so you can't read them from cin (this is a GCC extension).
So if you need an array with a size known only at runtime, I suggest std::vector.
Additionally, in C++ it is common practice to define the loop variable inside the scope of the for-loop, like so:
for (int i = 0; i < N ++i)
This keeps the surrounding scope cleaner. An array or struct can be initialized to zero in C++ with the following uniform initialization syntax:
SomeStruct x{}; // All members are default initialized (e. g. for built-in types: 0)
SomeType myArray[N][M]{}; // All elements are default initialized
A comment like this
// N -> rows, M -> columns
is really just saying you should be naming your variables rows/cols and not N/M. Make your code self-documenting ;)
I would not recommend using std::endl when you want a line-break, as it also flushes the buffer, which when writing to files could
have serious performance implications (for console output it's no problem). It is better practice to use '\n' for line-breaks and use std::flush explicitly if you need it.
I've omitted the outer while loop and made Rows/Columns constant for simplicity. With std::vector you should use Rows*Cols as size in a
1D array and then map a position (i,j) to the 1D index with the formula:
arr2D[i][j] = arr1D[i*Cols + j];
If you choose to let the user specify rows/cols and use
std::vector<int> vec(rows*cols);
As your array.
int main()
{
constexpr int rows{3};
constexpr int cols{3};
int numUserValues{};
cin >> numUserValues;
int arr[rows][cols]{};
cout << numUserValues << '\n';
for(int k=0; k<numUserValues; k++)
{
int r{};
int c{};
if (cin>>r>>c && r>=0 && r<rows && c>=0 && c<cols) {
arr[r][c] = 2;
}
}
for(int i=0; i<N; i++)
{
for(int j=0; j<M; j++)
{
cout<<arr[i][j]<<" ";
}
cout<<'\n';
}
return 0;
}
Your program is very user-unfriendly, since you have no prompts at all (e.g. cout << "Enter number of rows: ";, but this is my test-run, as you can see all elements are zero except for the ones I specified:
$ ./test
5
5
0 0
1 1
2 2
0 1
0 2
2 2 2
0 2 0
0 0 2
Your question is hard to answer, because you say "I want to print 1 at position ...", while your code says arr[r][c] = 2; ;)
"My code prints 1 at every position except first column", would mean for a 5x5:
0 1 1 1 1
0 1 1 1 1
0 1 1 1 1
0 1 1 1 1
0 1 1 1 1
Which is simply not the case and thus false information.
I want it to print 1 at certain specific places (r, c) where r is the row and c is the column
You are doing this:
cin>>r>>c;
arr[r][c] = 2;
when the input is "1 4", which invokes Undefined Behavior (UB), because you go out of range, since the 2D array you have is of 4x4 dimensions, thus you would need to do something like this instead:
arr[r - 1][c - 1] = 1;
since arrays are zero indexed. I changed 2 to 1, since this is what you asked for.
I have tried to reset the values of r and c to zero but nothing changes.
This has no actual effect, since r and c are going to be overwritten upon next input.
So I N - numbers I have to input, and I got M - numbers of places for those numbers and I need to find all combinations with repetition of given numbers.
Here is example:
Let's say that N is 3(I Have to input 3 numbers), and M is 4.
For example let's input numbers: 6 11 and 533.
This should be result
6,6,6,6
6,6,6,11
6,6,6,533
6,6,11,6
...
533,533,533,533
I know how to do that manualy when I know how much is N and M:
In example where N is 3 and M is 4:
int main()
{
int N = 3;
int M = 4;
int *numbers = new int[N + 1];
for (int i = 0; i < N; i++)
cin >> numbers[i];
for (int a = 0; a < N; a++)
for (int b = 0; b < N; b++)
for (int c = 0; c < N; c++)
for (int d = 0; d < N; d++)
{
cout << numbers[a] << " " << numbers[b] << " " << numbers[c] << " " << numbers[d] << endl;
}
return 0;
}
But how can I make algorithm so I can enter N and M via std::cin and I get correct resut?
Thanks.
First one short tip: don't use "new" or C-style arrays in C++ when we have RAII and much faster data structures.
For the solution to your problem I would suggest making separate function with recursion. You said you know how to do it manually so the first step in making it into algorithm is to tear down you manual solution step by step. For this problem when you solve it by hand you basically start with array of all first numbers and then for last position you just loop through available numbers. Then you go to the second last position and again loop through available numbers just now with the difference that for every number there you must also repeat the last spot number loop. Here is the recursion. For every "n"th position you must loop through available numbers and for every call the same function for "n+1"th number.
Here is a simplified solution, leaving out the input handling and exact print to keep code shorter and more focused on the problem:
#include <vector>
#include <iostream>
void printCombinations(const std::vector<int>& numbers, unsigned size, std::vector<int>& line) {
for (unsigned i = 0; i < numbers.size(); i++) {
line.push_back(numbers[i]);
if (size <= 1) { // Condition that prevents infinite loop in recursion
for (const auto& j : line)
std::cout << j << ","; // Simplified print to keep code shorter
std::cout << std::endl;
line.erase(line.end() - 1);
} else {
printCombinations(numbers, size - 1, line); // Recursion happens here
line.erase(line.end() - 1);
}
}
}
int main() {
std::vector<int> numbers = {6, 11, 533};
unsigned size = 4;
std::vector<int> line;
printCombinations(numbers, size, line);
return 0;
}
If you have any questions feel free to ask.
Totally there is no need for recursion here. This is a typical job for dynamic programming. Just get the first solution right for n = 1 (1 slot is available) which means the answer is [[6],[11],[533]] and then move on one by one by relying on the one previously memoized solution.
Sorry that i am not fluent in C, yet in JS this is the solution. I hope it helps.
function combosOfN(a,n){
var res = {};
for(var i = 1; i <= n; i++) res[i] = res[i-1] ? res[i-1].reduce((r,e) => r.concat(a.map(n => e.concat(n))),[])
: a.map(e => [e]);
return res[n];
}
var arr = [6,11,533],
n = 4;
console.log(JSON.stringify(combosOfN(arr,n)));
Normally the easiest way to do dynamic nested for loops is to create your own stack and use recursion.
#include <iostream>
#include <vector>
void printCombinations(int sampleCount, const std::vector<int>& options, std::vector<int>& numbersToPrint) {
if (numbersToPrint.size() == sampleCount) {
// got all the numbers we need, print them.
for (int number : numbersToPrint) {
std::cout << number << " ";
}
std::cout << "\n";
}
else {
// Add a new number, iterate over all possibilities
numbersToPrint.push_back(0);
for (int number : options) {
numbersToPrint.back() = number;
printCombinations(sampleCount, options, numbersToPrint);
}
numbersToPrint.pop_back();
}
}
void printCombinations(int sampleCount, const std::vector<int>& options) {
std::vector<int> stack;
printCombinations(sampleCount, options, stack);
}
int main()
{
printCombinations(3, {1,2,3});
}
output
1 1 1
1 1 2
1 1 3
1 2 1
1 2 2
1 2 3
1 3 1
1 3 2
1 3 3
2 1 1
2 1 2
2 1 3
2 2 1
2 2 2
2 2 3
2 3 1
2 3 2
2 3 3
3 1 1
3 1 2
3 1 3
3 2 1
3 2 2
3 2 3
3 3 1
3 3 2
3 3 3
Here is an algorithm to solve this, that does't use recursion.
Let's say n=2 and m=3. Consider the following sequence that corresponds to these values:
000
001
010
011
100
101
110
111
The meaning of this is that when you see a 0 you take the first number, and when you see a 1 you take the second number. So given the input numbers [5, 7], then 000 = 555, 001=557, 010=575 etc.
The sequence above looks identical to representing numbers from 0 to 7 in base 2. Basically, if you go from 0 to 7 and represent the numbers in base 2, you have the sequence above.
If you take n=3, m=4 then you need to work in base 3:
0000
0001
0002
0010
0011
0012
....
So you go over all the numbers from 0 to 63 (4^3-1), represent them in base 3 and follow the coding: 0 = first number, 1 = second number, 2 = third number and 3 = fourth number.
For the general case, you go from 0 to M^N-1, represent each number in base N, and apply the coding 0 = first number, etc.
Here is some sample code:
#include <stdio.h>
#include <math.h>
void convert_to_base(int number, char result[], int base, int number_of_digits) {
for (int i = number_of_digits - 1; i >= 0; i--) {
int remainder = number % base;
number = number / base;
result[i] = '0' + remainder;
}
}
int main() {
int n = 2, m = 3;
int num = pow(n, m) - 1;
for (int i = 0; i <= num; i++) {
char str[33];
convert_to_base(i, str, n, m);
printf("%s\n", str);
}
return 0;
}
Output:
000
001
010
011
100
101
110
111
Actually it's a hackerrank problem, the lonely integer. I understand the XOR logic used here. I just couldn't understand deeply the concept how is every number being processed after input. I have marked the line in code. Please help me in understanding it.
#include <iostream>
using namespace std;
int main()
{
int n, a, c = 0, i;
cin >> n;
for (i = 0; i < n; i++)
{
cin >> a;
c ^= a; // THIS LINE .... i WANT TO KNOW HOW IS THIS WORKING ?
// HOW IS COMPARISON BEING CARRIED OUT HERE ?
}
cout << a << endl;
return 0;
}
Program finds the number which is lonely, i.e. not in pair. XORing a number to itself results in 0. Using this concept all numbers are XORed one by one. A pair of number is xored and then the result is xored with another number in the input sequence and so on. At last the number which comes single will be left.
For example :
For the input 1 1 2 3 0 0 3
1 ^ 1 = 0
0 ^ 2 = 2
2 ^ 3 = 1
1 ^ 0 = 1
1 ^ 0 = 1
1 ^ 3 = 2
and 2 is lonely.
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++;
}
I'm writing a basic chess program to calculate how many sets you can make with the given chess figures. The data file:
4
22 3 5 6 2 0
1 1 1 1 1 1
8 4 4 4 1 2
5 3 3 3 0 2
The code:
#include <iostream>
#include <fstream>
#include <vector>
int main
(int argc, char *argv[])
{
std::fstream data_file;
size_t i, k;
std::vector<long> chess;
long t, n;
data_file.open("U1.txt", std::ios::in);
data_file >> n;
for (i = 0; i < n; i++)
chess.push_back(0);
for (i = 0; i < n; i++) {
for (k = 0; k < 6; k++) {
data_file >> t;
std::cout << t << " ";
chess[k] += t;
}
std::cout << std::endl;
}
data_file.close();
for (int i = 0; i < 6; i++)
std::cout << chess[i] << " ";
std::cout << std::endl;
data_file.open("U1rez.txt", std::ios::out);
data_file << n;
std::cout << n << std::endl;
data_file.close();
return EXIT_SUCCESS;
}
The output:
22 3 5 6 2 0
1 1 1 1 1 1
8 4 4 4 1 2
5 3 3 3 0 2
36 11 13 14 3 4
4
Why am I getting 3 and 4 at the end result just after 36, 11, 13 and 14 at line 5? When I print the test values I seem to get the right numbers but something goes terribly wrong in the addition of them in the vector container.
for (i = 0; i < n; i++)
chess.push_back(0);
.
.
.
for (i = 0; i < n; i++) {
for (k = 0; k < 6; k++) {
data_file >> t;
std::cout << t << " ";
chess[k] += t;
}
std::cout << std::endl;
}
here, you initialized n(=4) places in the vector, but here you are accessing the index 4 and 5 of the vector chess which is causing the addition problem.
On an unrelated note, you will have a much easier time with C++ if you let go of some of the rules imposed by C.
The C++ API uses scope-bounded resource management; i.e. there's no need to explicitly close the file handle here, since the class does this for you when its destructor is called at the end of the declared scope.
Prefer std::cout << "\n" to std::cout << std::endl, unless you actually intend to insert a newline and flush the buffer. Many C++ programmers still use printf, and I personally think that it's a lot more elegant than C++'s ugly standard solution to IO -- feel free to use printf.
Do you find your code easier to manage and read when you declare your variable where they are used (e.g. for (size_type i = 0; ... ; ...)), rather than at the beginning of your method? This also allows the compiler to potentially make better choices about register usage, since it has more information about the scopes of your temporary variables.
Here are a few features of C++11 that can also save you some time:
Automatic type inference: when the compiler can infer the type of a variable, it's not necessary for you to explicitly specify it; you can use auto instead (e.g. auto x = parse_data();).
Range-for: if you are operating on a container that provides global definitions begin() and end() (such as any standard container), then instead of this:
typedef typename container_type::const_iterator iter;
for (iter i = begin(container), iter l = end(container); i != l; ++i) { ... }
You can do this:
for (const auto& x : container) { ... }
I just wanted to give you a few quick pointers that can save you some time.