I am quite new to progamming, I would like to parse data in a format like this:
4 ((182, 207), (385, 153), (638, 639), (692, 591))
First number states the number of pairs that will occur. I want to save first number of each pair as X axis and second number of each pair as Y axis.
In my head for now I wanted to save entire line via scanf and then try to work around the amount of brackets and commas but I am not sure if that is the right method or how to implement it properly. I do not want to use any built in containers or string. I tried to do it straight away via scanf doing something like
for(int i= 0; i < pair_count;i++){
scanf("(%d, %d)",tabx[i],taby[i])
}
but it does not work :(. I don't know how to format the scanf correctly I guess or my idea on how to do it is completely wrong.
scanf() expects the address to a variable, not the variable itself. So try:
scanf("(%d, %d)",&tabx[i],&taby[i]);
You can also try to use c++ streams:
for(int i= 0; i < pair_count;i++){
char d1,d2,d3;
if ( (cin >> d1 >> tabx[i] >> d2 >> taby[i] >> d3) && d1=='(' && d3==')' && d2==',') {
... //process data
}
else cout << "Wrong input !"<<endl;
}
You have to input all matching characters. It's a bit tricky, because , is not present after last pair of numbers.
Following sample code solves your problem.
#include <cstdio>
#include <cstdlib>
int main() {
// 4 ((182, 207), (385, 153), (638, 639), (692, 591))
int pair_count;
scanf("%d", &pair_count);
scanf(" (");
int* tabx = new int[pair_count];
int* taby = new int[pair_count];
for (int i = 0; i < pair_count-1; ++i) {
if (scanf("(%d, %d), ", &tabx[i], &taby[i]) < 2) {
fprintf(stderr, "Input error!\n");
return EXIT_FAILURE;
}
}
if (scanf("(%d, %d))", &tabx[pair_count-1], &taby[pair_count-1]) < 2) {
fprintf(stderr, "Input error!\n");
return EXIT_FAILURE;
}
for (int i = 0; i < pair_count; ++i) {
printf("%d %d\n", tabx[i], taby[i]);
}
delete[] tabx;
delete[] taby;
}
Alternatively, you can read the entire input to string and replace all (, ) and , with (space). After that you can simply parse numbers. On the other hand, this removes validation of data format.
Related
I have an array that reads data from a file, the data is binary digits such as 010011001001 and many others so the data are strings which I read in to my 2d array but I am stuck on comparing each value of the array to 0. Any help would be appreciated.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string myArr[5000][12];
int i = 0, zeroCount = 0, oneCount = 0;
ifstream inFile;
inFile.open("Day3.txt");
while(!inFile.eof())
{
for(int i = 0; i < 5000; i++)
{
for(int j = 0; j < 12; j++)
{
inFile >> myArr[i][j];
j++;
}
i++;
}
}
for(int j = 0; j < 12; j++)
{
for(int i = 0; i < 5000; i++)
{
if(myArr[i][j].compare("0") == 0)
{
zeroCount++;
}
else
{
oneCount++;
}
i++;
}
if(zeroCount > oneCount)
{
cout << "Gamma is zero for column " << i << endl;
}
else
{
cout << "Gamma is One for column " << i << endl;
}
j++;
}
}
some input from the text file:
010110011101
101100111000
100100000011
111000010001
001100010011
010000111100
Thank you for editing you question and providing more information. Now, we can help you. You have 2 major misunderstandings.
How does a for loop work?
What is a std::string in C++
Let us start with the for loop. You find an explanation in the CPP reference here. Or, you could look also at the tutorial shown here.
The for loop has basically 3 parts: for (part1; part2; part3). All are optional, you can use them, but no need to use them.
part1 is the init-statement. Here you can declare/define/initialize a variable. In your case it is int i = 0. You define a variable of data type int and initialize it with a value of 0
part2 is the condition. The loop will run, until the condition becomes false. The condition will be check at the beginning of the loop.
part3 is the so called iteration-expression. The term is a little bit misguiding. It is basically a statement that is executed at the end of the loop, before the next loop run will be executed and before the condition is checked again.
In Pseudo code it is something like this:
{
init-statement
while ( condition ) {
statement
iteration-expression ;
}
}
which means for the part of your code for(int j = 0; j < 12; j++)
{
int j = 0; // init-statement
while ( j < 12 ) { // while ( condition ) {
inFile >> myArr[i][j]; // Your loop statements
j++; // Your loop statements PROBLEM
j++; // iteration-expression from the for loop
}
}
And now you see the problem. You unfortunately increment 'j' twice. You do not need to do that. The last part3 of the for loop does this for you already.
So please delete the duplicated increment statements.
Next, the std::string
A string is, as its names says, a string of characters, or in the context of programming languages, an array of characters.
In C we used to write actually char[42] = "abc";. So using really a array of characters. The problem was always the fixed length of such a string. Here for example 42. In such an array you could store only 41 characters. If the string would be longer, then it could not work.
The inventors of C++ solved this problem. They created a dynamic character array, an array that can grow, if needed. They called this thing std::string. It does not have a predefined length. It will grow as needed.
Therefore, writing string myArr[5000][12]; shows that you did not fully understand this concept. You do not need [12], becuase the string can hold the 12 characters already. So, you can delete it. They characters will implicitely be there. And if you write inFile >> myString then the extractor operator >> will read characters from the stream until the next space and then store it in your myString variable, regardless how long the string is.
Please read this tutorial about strings.
That is a big advantage over the C-Style strings.
Then your code could look like:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string myArr[5000];
int zeroCount = 0, oneCount = 0;
ifstream inFile;
inFile.open("Day3.txt");
while (!inFile.eof())
{
for (int i = 0; i < 5000; i++)
{
inFile >> myArr[i];
}
}
for (int i = 0; i < 5000; i++)
{
zeroCount = 0; oneCount = 0;
for (int j = 0; j < 12; j++)
{
if (myArr[i][j]== '0')
{
zeroCount++;
}
else
{
oneCount++;
}
}
if (zeroCount > oneCount)
{
cout << "Gamma is zero for column " << i << endl;
}
else
{
cout << "Gamma is One for column " << i << endl;
}
}
}
But there is more. You use the magic number 5000 for your array of strings. This you do, because you think that 5000 is always big enough to hold all strings. But what, if not? If you have more than 5000 strings in your source file, then your code will crash.
Similar to the string problem for character arrays, we have also a array for any kind of data in C++, that can dynamically grow as needed. It is called std::vector and you can read about it here. A tutorial can be found here.
With that you can get rid of any C-Style array at all. But please continue to study the language C++ further and you will understand more and more.
Ther are more subtle problems in your code like while(!inFile.eof()), but this should be solved later.
I hope I could help
Basically, I'm reading a file and trying to store the data in a 2D, for the differentiation between rows and columns I use the logic below:
int rows=0,column=0;
char arr[50][50];
while(my_file.eof()==0){
my_file.get(ch);
if(ch=='\n'){
rows++;
}
arr[rows][column]=ch;
column++;
}
for(int j=0;j<rows;j++){
for(int k=0;k<column;k++){
cout<<arr[j][k];}
}
But the when I run It shows the following output: https://i.stack.imgur.com/XzhST.png
And the text file data is:
I am going to school
hi!
Hello
guide me a bit...
Hmm, a 2D char array can indeed be used to store an number of lines, but you should control that you never try to store more than 50 characters for a single line, and that you never try to ouput more characters for a line than what it initially contained.
Here is a minimal fix of your code:
int rows = 0, column = 0;
char arr[50][50] = { {0 } }; // ensure the array is initialized with '\0' chars
for (;;) {
my_file.get(ch);
if (!my_file) break; // eof shall be tested AFTER a read operation
if (ch == '\n') {
rows++;
if (rows == 50) break; // no more than 50 lines
column = 0; // reset column index for next line
}
else if (column < 50) { // no more than 50 columns
arr[rows][column] = ch;
column++;
}
}
for (int j = 0; j < rows; j++) {
for (int k = 0; k < 50; k++) {
if (arr[j][k] == 0) break; // stop on end of line
std::cout << arr[j][k];
}
std::cout << '\n'; // and display the end of line
}
And as you have been said this is rather C-ish... I assume it is only for learning how 2D arrays can work.
As pointed out in comments, you'd be much better off using a std::vectorstd::string to store the strings.
But, this looks like a homework assignment to read then print each byte separately, so let's have a look... I'll add one of the ways this is usually done at the end of this post.
Your output looks like this:
It looks like you are displaying characters beyond the bondary of the strings, or that your strings are not null terminated... Turns out it's both.
Your code:
int rows = 0, column = 0;
char arr[50][50]; // <-- your array is not initialized, while that is not
// a big issue, filling the array with zeroes is easy:
// char arr[50][50] = {};
while (my_file.eof() == 0) {
my_file.get(ch);
if (ch == '\n') {
rows++; // <-- you pass to the next string, but do not put a
// null character to properly terminate your strings
// while this could have been avoided by initializing
// the array, it's best to do it explicitely.
// replace above line contents by:
arr[row][column] = '\0';
if (++row >= 50) // consider using named constants for the size of your array.
break; // No use keeping on reading strings if there is no
// more room to store them
}
arr[rows][column] = ch; // <-- I suspect a bunch un undefined stuff will
// start happening when column >= 50
column++;
// Try replacing above code with:
if (column < 50) // consider using named constants for the size of your array.
arr[rows][column++] = ch;
}
// make sure the last string is null terminated.
if (row < 50 && column < 50)
arr[row][column] = '\0';
// note that strings that are 50 bytes long are NOT null terminated.
// that's important to keep in mind, and only workss because we'll print
// byte by byte.
// your original print routine prints out all characters in the array, even
// stuff that was not in the original file...
for (int j = 0; j < rows; ++j){
for (int k=0 ; k < column; ++k){ // <-- you need to check for a null
// terminating character here...
// also, column is the length of the last
// string in the array. This is not a very
// useful value for displaying any other
// strings, is it?
// try this:
for (int k = 0; k < 50 && arr[j][k] != '\0'; ++k)
cout << arr[j][k];
}
cout << '\n'; // insert a newline after each string.
}
As you can tell, this is overly complex for doing a very common operation... Here's a more concise way of doing the same thing:
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
int main()
{
std::vector<std::string> arr;
std::ifstream ifs("testfile.txt");
while (ifs && !ifs.eof())
{
std::string str;
std::getline(ifs, str);
arr.push_back(str);
}
for (size_t i = 0; i < arr.size(); ++i)
std::cout << arr[i] << '\n';
return 0;
}
Because you haven't compile the array yet
char arr[50][50];
for (int r = 0; r < 50; r++){
for (int c = 0; c < 50; c++){
arr[r][c] = ' ';}
}
I'm trying to solve this problem from an online judge (Codeforces):
One day Deivis came across two Vectors of integers A and B, and wondered, could it be possible to form the number X by adding an element of A to another element of B?
More formally, it is possible to choose two indexes i and j such that Ai + Bj = x?
Input
The first entry line is two integers n and x. The second line contains n numbers, the vector A. The third and last line contains n numbers, vector B.
Output
Print 1 if it is possible to form the number x from a sum of one element of each vector, and 0 otherwise."
My problem is that I can not fill in the second vector, when the program runs on the site it fills the vector with zeros. I am using C ++, here's my code:
#include <bits/stdc++.h>
using namespace std;
#define MAX 10
int main()
{
int n, x, i = 0, j = 0, resp = 0, sum;
vector<int> vetA(MAX), vetB(MAX);
cin >> n >> x;
while (scanf("%d", &vetA[i]) == 1)
i++;
while (scanf("%d", &vetB[j]) == 1)
j++;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
sum = vetA[i] + vetB[j];
if (sum == x)
{
resp = 1;
goto END;
}
}
}
END: printf("%d", resp);
return 0;
}
I try to use getchar() after each while loop, but seems that on the site it does not do data capture like on a keyboard, and so the second vector isn't receiving any data. I've also tried to capture data as a std::string but that doesn't work.
Can someone help me?
Here are some hints/examples to compare your program to:
#include <iostream> //Include each standard library seperately
#include <vector> //#include <bits/stdc++.h> is bad practice
// Only declare variables as they are used.
int n; // Better coding practice is one variable per line.
int x; // Competitions shouldn't care how many lines.
if (!(std::cin >> n >> x)) //This is basically the same as cin.fail()
{
std::cerr << "Error inputting data.\n";
return 1;
}
// Now create the vectors, after the size has read in.
std::vector<int> vetA(n);
std::vector<int> vetB(n);
// The number of elements is known, so use a "for" loop.
for (size_t i = 0; i < n; ++i)
{
std::cin >> vetA[i];
}
for (size_t i = 0; i < x; ++i)
{
std::cin >> vetB[i];
}
You should add in some error handling because your program will be given some invalid inputs.
The inputs and vector sizes are examples since you didn't specify the input format in your Post.
I am working on a program in C++ that will read integers from a file, then pass them to a function that checks for a Subset Sum.
The file is formatted like so:
number of cases n
sum for case 1
list of integers separated by a space
sum for case
list of integers separated by a space
sum for case n
list of integers separated by a space
My problem now lies in how to read the list of integers into an array to be passed to my function.
This is my main so far:
fstream infile("subset.txt");
if(infile.is_open()){
int numCases, num;
infile >> numCases;
while(infile >> num){
for(int i = 0; i < numCases; i++)
{
int sum;
int set[30];
num >> sum;
for(int i = 0; i < 30; i++)
{
if(num == '\n')
{
sum[i] = -1
}
else
{
num << sum[i]
}
}
int n = sizeof(set)/sizeof(set[0]);
if(subsetSum(set, n, sum) == true)
printf("True");
else
printf("False");
}
}
}
else
printf("File did not open correctly.");
return 0;
Any help you guys can give me would be greatly appreciated.
Yes, this is for an assignment, so if you would rather just give me hints that would be appreciated as well. The assignment is for the algorithm and I have that working, I just need a hand with the I/O.
I would read the line containing the list of numbers using std::getline, then use an istringstream to parse numbers out of that string.
I'd also use a std::vector instead of an array to hold the numbers. For the actual parsing, I'd probably use a pair of std::istream_iterators, so the code would look something like this:
while (infile >> sum) {
std::getline(infile, line);
std::istringstream buffer(line);
std::vector<int> numbers{std::istream_iterator<int>(buffer),
std::istream_iterator<int>()};
std::cout << std::boolalpha << subsetSum(numbers, sum);
}
I am making a Sudoku program and my i have a test.txt file that reads
53__7____
6__195___
_98____6_
8___6___3
4__8_3__1
7___2___6
_6____28_
___419__5
____8__79
where the "_" are actually spaces. The reason i give you _ is so you can see that there are literally only 9 characters on each line.
I was thinking that I would have to do something like having GRID[row][column], however I frankly don't know what types I should put my arrays as and I am just lost.
I simply want to make it so when i want to output say GRID[0][0] it returns 5, while if i ask for GRID[0][3] it returns a ' '.
It is getting it so the array store both the numbers and the spaces is where i am getting completely lost
What I currently have tried so far:
int main()
{
ifstream myfile(test.txt);
string line;
char sudoku_grid[9][9];
if (myfile.is_open())
{
while(myfile.good())
{
getline(myfile, line);
cout << sudoku_grid[line] << endl;
}
myfile.close();
}
else cout << "error";
return 0;
}
it returns the error line 12: no match for 'operator [ ]' in 'sudoku_grid[line]'
Here is my attempt though guidelines through you guys:
int main()
{
ifstream myfile(test.txt);
string line;
char sudoku_grid[9][9];
if (myfile.good())
{
for(int i = 0; i < 9; i++)
{
getline(myfile, line);
for(int j = 0; j < 9; j++)
{
if (line[j] == ' ')
sudoku_grid[j][i] = -1;
else sudoku_grid[j][i] = line[i];
}
cout << sudoku_grid[i] << endl;
}
myfile.close();
}
else cout << "error";
return 0;
}
The result is a very awkward answer of strange letters and a new numbers.
I'll just give you the algorithm/logic, not going to write the code for you. Try it and come back when stuck.
Initialize output in memory 2D array: numbers[9][9]
Open the file
Until there is no line left in the file:
a. Get the line i
b. Until there are no more characters in the line:
b1. Get each character of the line c
b2. If the character is not space, then numbers[i]=c, else numbers[i]=-1
Your array can be made up of int and in b2 if a whitespace is encountered you can insert -1 to indicate the absence of a number. Of course your code manipulating numbers array needs to take that into account.
Since you need to store both chars and integer type values, use char. each of your integer lies in the range 0-9, so can be stored as a character.
char Grid[9][9];
now you can read each character from the string and store it in the array. It will not only keep your spaces intact but also each character. Always remember to use ASCII codes to access the elements of the grid. For 0-9, ASCII codes are 48-57, ASCII code for space is 32.
Hope it helps...
Edit code: Here is the simplest example... PLace your test file in d:, or edit the path of file in code
int main (void)
{
FILE *fp = fopen("d:\\test.txt","r");
char sudoku_grid[9][9], ch;
// I am assuming that file is valid and data in that is also valid
if(fp)
{
for(int i = 0; i < 9; i++)
{
for(int j = 0; j < 9; j++)
{
//too read each character
ch = fgetc(fp);
sudoku_grid[i][j] = ch;
}
// to read '\n' from the line
ch = fgetc(fp);
}
//for checking if data went correctly
for(int i = 0; i< 9;i++)
{
for(int j= 0; j<9;j++)
cout<<sudoku_grid[i][j];
cout<<endl;
}
}
return 0;
}
In the first code you get the error message because sudoku_grid can
only be indexed by numbers and not by strings.
In the second code the line
sudoku_grid[j][i] = line[i];
should probably be
sudoku_grid[j][i] = line[j];
Does this answer your question?