I am using scanf to take input for a graph. The input is as follows :
8
1 2
3 3 5 6
2 4 7
2 3 8
2 1 5
1 7
2 6 4
0
The first integer (8) is the number of vertices, followed by 8 line. The first integer in each is the number of outgoing edges from vertex 1 in the first line, vertex 2 in the second line and so on.
The function i have written is as follows :
void getInput() {
//init();
int numVertex; int numTest;
scanf("%d", &numVertex);
for(int i =1 ; i <= numVertex;i++) {
int ver,nC; vector<int> vList;
//fscanf(file,"%d", &ver);
scanf("%d", &nC);
for(int j=0;j<nC;j++) {
int temp ;
scanf("%d", &temp);
vList.push_back(temp);
}
props pr = {-1,-1 , vList};
graph.insert(make_pair(i, pr) );
}
}
However, the output for the last line of my input becomes weird and it basically repeats the last digit of its previous line multiple times. For the above input , the output I am getting :
1 : 2
2 : 3 5 6
3 : 4 7
4 : 3 8
5 : 1 5
6 : 7
7 : 6 4
8 : 4 4 // this is where it should give nothing
Can anyone tell me whats going wrong here? The exact same sequences of conversions, when I convert to taking input through file gives me the right output.
Can someone please point me to any error?
Do it like this:
if (scanf("%d", &nC) != EOF) {
for(int j=0;j<nC;j++) {
int temp ;
scanf("%d", &temp);
vList.push_back(temp);
}
props pr = {-1,-1 , vList};
graph.insert(make_pair(i, pr) );
}
This will check if the read was successful. The repetition of the last line of input is a well known issue and occurs because the last read attempt fails (because end of file has reached) and scanf returns the same result as its previous call.
What is props?
Whatever it is, doing C-style struct initialization on something containing an std::vector is asking for trouble - the results are undefined and almost surely not what you want.
Your input code seems OK though, despite lack of error-checking as noted in another answer.
Related
I was trying to solve a problem where I had to sort so I used the standard library std::sort function but I get a wrong output in the 2nd test case:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,i;
cin>>n;
int arr[n-1];
for(i=1;i<=n-1;i++)
cin>>arr[i];
int size=sizeof(arr)/sizeof(arr[1]);
sort(arr,arr+size);
for(i=1;i<=n-1;i++)
cout<<arr[i]<<" ";
cout<<endl;
}
return 0;
}
I/P:
2
5
1 2 5 4
10
1 2 3 4 5 6 7 8 10
Expected O/P:
1 2 4 5
1 2 3 4 5 6 7 8 10
Actual O/P:
1 2 4 5
2 3 4 5 6 7 8 2013562 10
First of all, int arr[n-1]; is a variable length array. That's not actually part of C++, even though some compilers will tolerate it nevertheless. In most cases you can just use std::vector<int>(n-1); instead.
But look at this loop:
for(i=1;i<=n-1;i++)
cin>>arr[i];
You're starting at 1 and got all the way up to n-1, however your array goes from arr[0] to arr[n-2]. So you got undefined behavior because you're writing one past the size of the array, and you also don't write to the first position (leading to more undefined behavior when you try to sort with this uninitialized value still present).
Instead, the loop should be for(i=0;i<n-1;i++) The same applies to where you're printing it. You can then sort the vector this way:
sort(arr.begin(), arr.end());
Also note that by doing n-1 you're always reading in and handling one less value that the user inputs, I'm not sure if that's your intention. If you want that, you could also just decrease n by one after reading it in instead of writing n-1 in multiple places.
I was solving a problem on codechef:
https://www.codechef.com/NITWMA01/problems/QPALIN.It required to input m number of input cases after getting the value of m from the user. I always used to run a loop of:
while(m--)
{//input test cases}, but in this problem I don't know why the loop is running less than m times when I have to get input cases m times. I tried running the code with the sample input(with m having 6) but main() returned 0 after getting just 4 inputs(and printint respective outputs wherever necessary).
My code is as follows:
#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
int main()
{
int n,m,op,x,l,r,i,j,xorpair=0;
char k,s[100000];
scanf("%d",&n);
scanf("%s",s);
scanf("%d",&m);
for(j=0;j<m;j++)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d",&x);
scanf("%c",&k);
s[x-1]=k;
}
else
{
xorpair=0;
scanf("%d%d",&l,&r);
for(i=l-1;i<r;i++)
{
xorpair^=s[i]-'0';
}
if(xorpair==0)
{
printf("YES\n");
}
else printf("NO\n");
}
}
return 0;
}
PS: I have replaced cin with scanf. Also I believe I was not able to properly convey what problem actually I am facing. So here's the test case that explains it more clearly:
(What it should be like)
Sample input:
7
abbacca
6
2 1 4
1 1 z
2 1 4
1 4 z
2 1 4
2 5 7
Sample output:
YES
NO
YES
YES
Following is the problem that I am facing:
When I run the program for the above input, this is what appears on the output screen
7
abbacca
6
2 1 4
YES
1 1 z
2 1 4
NO
1 4 z
Process returned 0 (0x0)
I am not able to enter inputs 6 times and after 4th input it returns 0.
scanf("%c" does not do what you seem to expect. It reads just the ' ' before the char you want. Then the next tries at reading op and x fail leaving op still equal to 1, so you do two of operation 1 for every once that you intended to.
So I have a text file which has information about basketball players and it looks like this:
8
9 5 7 -5 13 -4 11
7 5 -3 12 -5 17 -3
25 7 12 -3 5 -5 7 -5 3
14 5 12 -3 10 -7 8
5 1 -40
33 5 15 -5 9 -3 8
11 5 -12 8 -5 12 -3
13 5 3 -4 25 -5 3
First integer in the first line shows how many players are there. In every other line the first integer is the number of the player, the second integer shows how many more integers there are in the line and each of the following integers shows if the player is playing (if the integer is positive) or sitting on the bench (if the number is negative).
I want to read the info to an array of structures which look like this:
struct player
{
int nr;
int k;
int bus[];
};
I've written a function to do so:
void skaitymas(int &n, player mas[])
{
ifstream duom("U1.txt");
duom >> n;
for (int i=0; i < n; i++) {
duom >> mas[i].nr >> mas[i].k;
for (int f=0; f < mas[i].k; f++) {
duom >> mas[i].bus[f];
}
}
}
When I run it the program seems to work, however the arrays of structures save unexpected values. After adding some cout commands in random places, I found out that it saves the correct values to the array the first time, first for loop loops, but after some iterations it changes the values of the previous arrays. For example, when i in the for loop equals 1 then mas[1].bus[0] is saved to be -3, as it should be, however after i changes to 2, mas[1].bus[0] changes to 25.
I would appreciate it if you would help me to figure it out, why the numbers in the arrays change to other random numbers from the text file, even if I don't do anything to them.
There are several problems with your code. The most obvious is
that int bus[] declares a variable with an incomplete type,
and it is illegal in C++ to declare a member variable with an
incomplete type. Unless your compiler is seriously broken, this
shouldn't compile; at the very latest, you should get an error
when you write mas[i], since there is no possible way of doing
pointer arithmetic on a pointer to an incomplete type. The way
to declare your class is:
struct Player
{
int nr;
std::vector<int> bus;
};
Once you do this, you should be able to compile. Still, it's
very poor C++ to read in counts of the following elements. The
correct way of doing this would be to drop the counts in the
file: the number of lines is the number of players, and the
number of integers following the first in the line is the number
of integers following the first in the line. If you do this,
you end up with something like:
std::vector<Player> skaitymas()
{
std::ifsteram duom( "U1.txt" );
if ( !duom.is_open() ) {
// Some sort of error handling, maybe an exception.
}
std::vector<Player> results;
std::string line;
while ( std::getline( duom, line ) ) {
std::istringstream s( line );
int nr;
s >> nr;
if ( !s ) {
// Format error...
}
results.push_back(Player{ nr });
while ( s >> nr ) {
results.back().bus.push_back( nr );
}
}
return results;
}
Everything is done dynamically (which is very simple in C++).
Each line of my file consists of an unknown number of integers, which are separated by spaces. I would like to read in each line as a vector of those integers.
Here is an example of such file:
11 3 0 1
4 5 0 3
2 3 4 1
23 4 25 15 11
0 2 6 7 10
5 6 2
1
11
I've been able to read in small amounts of data successfully using the following method (Note that outer_layers is a vector that contains these vectors I'm trying to populate):
for (int i = 0; i < outer_layers.size(); i++)
{
while (in >> temp_num)
{
outer_layers[i].inner_layer.push_back(temp_num);
if (in.peek() == '\n')
break;
}
}
However, when I'm trying to read in larger amounts of data, sometimes it'll read in two lines under one vector. In one of the files, out of 24 lines, it read two-liners on two occasions, so last two vectors did not have any data.
I can't wrap my head around it. Any ideas what I'm doing wrong?
EDIT: Something interesting I've noticed in some of the lines of the trouble-maker file is this:
Let's say there are three lines.
23 42 1 5
1 0 5 10
2 3 11
Line #1 reads in just fine as 23 42 1 5; however, line #2 and #3 get read together as 1 0 5 10 2 3 11.
In Notepad++ they look just fine, each on their own lines. However, in Notepad, they look like this:
23 42 1 51 0 5 10 2 3 11
If you notice, the 5 (last integer of line #1) and 1 (first integer of line #2) are not separated by spaces; however, 10 and 2 are separated by a space.
I've noticed that behavior on any double-read-in lines. If they are separated by a space, then they're both read in. Not sure why this is occurring, considering there should still be a new line character in there for Notepad++ to display the on separate lines, am I right?
I'm not sure how your outer_layers and inner_layers is setup, but you can use std::getline and std::stringstream to fill your vectors something like this :
std::vector< std::vector<int> > V ;
std::vector <int> vec;
std::ifstream fin("input.txt");
std::string line;
int i;
while (std::getline( fin, line) ) //Read a line
{
std::stringstream ss(line);
while(ss >> i) //Extract integers from line
vec.push_back(i);
V.push_back(vec);
vec.clear();
}
fin.close();
for(const auto &x:V)
{
for(const auto &y:x)
std::cout<<y<<" ";
std::cout<<std::endl;
}
I have data for which using cin/in is too slow.
There are three integers per line :
1 2 2
3 4 1
5 6 122
6 4 7
How to read-in each line in loop, to achive result (for first iteration) :
x==1;
y==2;
z==2;
etc.
?
How to to do it using cstdio::scanf ?
Use this:
while(scanf("%d %d %d", &a, &b, &c) != EOF) {
... do stuff ...
}