Confused by how stringstream seems to work [duplicate] - c++

This question already has answers here:
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Closed 6 months ago.
I'm new to c++. Currently I'm learning how to read and write to a file. I've created a file "nb.txt" with content like this:
1 2 3 4 5 6 7
2 3 4 5 6 7 9
I'm using a simple program to read this file, looping until reached EOF.
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ifstream in("nb.txt");
while (in) {
int current;
in >> current;
cout << current << " ";
}
}
What I'm expecting is the program will output all of the values.
But what I'm really getting is this:
1 2 3 4 5 6 7 2 3 4 5 6 7 9 9
There's a multiple "9" in the output. I don't understand what's happening! Is it because of the while loop?
Can anyone help me to figure out why there is another "9"? Thanks!

The problem is that after you read the last value(which is 9 in this case) in is not yet set to end of file. So the program enters the while loop one more time, then reads in(which now sets it to end of file) and no changes are made to the variable current and it is printed with its current value(which is 9).
To solve this problem, you can do the following:
int main() {
ifstream in("nb.txt");
int current=0;
while (in >> current) { //note the in >> curent
cout << current << " ";
}
}
The output of the above program can be seen here:
1 2 3 4 5 6 7 2 3 4 5 6 7 9

Related

C++ double recursion [duplicate]

This question already has answers here:
What is a debugger and how can it help me diagnose problems?
(2 answers)
Good debugger tutorial for beginners [closed]
(1 answer)
Closed 2 years ago.
Hello i was having some funny with my code lately and i met strange output of double recursion. I was trying to understand it but im not so lucky to know the answer yet. Maybe u ll help me with tis problem . Why this program has so weird output? output : 4 3 2 1 1 2 1 1 3 2 1 1 2 1 1. I figure out that firstly it just do first somefunc call so printing 4321 , next somefunc has output like 1234. firs it decrement 1 so its 0 next decrement 2 by 1 so its 1 and then decrement then 3 decrement by 1 its 2 and 1 , decrement 4 by 1 untill 0 so its 321 its logically output will be 4321 2 1 3 2 1 but i dont understand the rest.
#include <iostream>
using namespace std;
void somefunc(int c)
{
if(c>=1)
{
cout <<c<<" ";
somefunc(c-1);
somefunc(c-1);
}
}
int main()
{
somefunc(4);
return 0;
}

Getting funny output for insertion sort

I'm trying to implement insertion sort. My logic may be wrong because I was unable to complete my code due to some error.
I want help with values changing absurdly while executing. Also, there is a similar repeating element question but it is in python and it went over my head. so, please don't mark it duplicate.
As you can see I have initialized a temporary variable index, why you ask? because the value of N is changing during run time.
secondly, Value is getting repeated when sorting is taking place.
I'm using codeblocks 17.2.
#include<iostream>
#include<utility>
#include<algorithm>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
int arr[100];
int N,index;
cin>>N;
for(int i=0;i<N;i++)
{
cin>>arr[i];
}
index=N; // using temperory variable
for(int l=0;l<index;l++)
{
for(int j=l+1;j>=0;j--)
{
if(l==index-1 || j==0) //Working fine now
break;
if(arr[j]<arr[j-1])
{
swap(arr[j],arr[j-1]);
}
}
cout<<N<<endl; //value of n is changing but why
for(int k=0;k<index;k++)
{
cout<<arr[k]<<" "; //value of array is also coming wrong
}
cout<<"\n";
}
return 0;
}
N=7
and elements of the array to be
7 8 5 2 4 6 3
output is
7 //these are the values of N which is changing
7 8 5 2 4 6 3
5
7 7 8 2 4 6 3
2
5 7 7 8 4 6 3
2
4 5 7 7 8 6 3
2
4 5 6 7 7 8 3
2
3 4 5 6 7 7 8
0
2 3 4 5 6 7 7
check for boundary condition and when non-existing array index is accessed it will give undefined behavior. In this case, it appears that N was stored right before arr and it changed when you modified arr[-1].

why this code takes one less input from standard input? [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 5 years ago.
Giving input as:
Input:
3
1 2 3
4 5 6 7
8 9 10 11 12
Expected Output:
1 2 3
4 5 6 7
8 9 10 11 12
But it is giving the Output-
1 2 3
4 5 6 7
Why it is not giving the last line ? Is there any mistake in my code?
#include <iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;
int main() {
int t;
cin>>t;
while(t--)
{ string str;
getline(cin,str,'\n');
cout<<str<<endl;
}
return 0;
}
It's because cin>>t doesn't read the end-of-line. The first time you call getline you're getting an empty string.
I can think of a couple of ways of getting around this offhand. First is to skip over the whitespace at the end of the first number, since a newline counts as whitespace. Unfortunately this will also skip whitespace at the beginning of the next line.
cin >> t >> std::ws;
The other way is to use getline to skip past the end of the line and ignore the string you get back.
cin >> t;
getline(cin, str, '\n');

Why would a error free code not give the expected result on one machine but yes on the other

I'm having a problem with a part of code. It should work,since it is error free, and it has no logical problems since it does work on someone else pc, but on my computer the result is the same as the input.
code(runnable):
#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;
class RAngle{
public:
int x,y,l;
RAngle(){}
RAngle(int i,int j,int k){
x=i,y=j,l=k;
}
bool operator<(const RAngle& rhs)const{
if(l < rhs.l){
return true;
}
return 0;
}
friend ostream& operator << (ostream& out, const RAngle& ra){
out << ra.x << " " << ra.y << " " << ra.l;
return out;
}
friend istream& operator >>( istream& is, RAngle &ra){
is >> ra.x;
is >> ra.y;
is >> ra.l;
return is ;
}
};
void descrSort(vector <RAngle> &l){
for(unsigned i=0; i<l.size();i++){
cout<<l[i]<<endl;
}
cout << "==================" << endl;
sort(l.begin(),l.end());
reverse(l.begin(),l.end());
for(unsigned i=0; i<l.size();i++){
cout<<l[i]<<endl;
}
}
void readData(vector <RAngle> &l){
RAngle r;
ifstream f_in;
f_in.open("test.txt",ios::in);
for(int i=0;i<10;++i){
f_in >> r;
l.push_back(r);
}
}
int main(){
vector <RAngle> a;
readData(a);
descrSort(a);
return 0;
}
DATA:
1 7 31
2 2 2
3 3 3
4 5 1
10 5 1
1 1 9
10 3 10
4 5 7
5 4 15
2 3 25
1 7 31
The output on other machine(only print part after, the descr sort):
1 7 31
2 3 25
5 4 15
10 3 10
1 1 9
4 5 7
3 3 3
2 2 2
10 5 1
4 5 1
on my computer(hoel output):
1 7 31
2 2 2
3 3 3
4 5 1
10 5 1
1 1 9
10 3 10
4 5 7
5 4 15
2 3 25
==================
1 7 31
2 2 2
3 3 3
4 5 1
10 5 1
1 1 9
10 3 10
4 5 7
5 4 15
2 3 25
This means your code has an error. C and C++ let things compile and run that actually have errors in them. Like this:
int i;
std::cout << i << std::endl;
Will do different things on different machines. I would call it an error. The compiler won't.
Now as for where your error is, here is my "use a debugger" speech. Use a debugger. It will take you less time to use a debugger and have a decent chance of finding the error than it did for me to read your code to see if anything jumped out. Compile with -g. Google "gdb cheat sheet." Run with gdb. Follow the cheat sheet. See where your code does something unexpected.
Seems smart to do this on the machine that is giving the wrong output. And see where it's doing something wrong.
To expand on what #djechlin said, what you most likely have is "undefined behavior".
Most programming languages strictly define what can and can't be done, and compiler writers use that to generate compiler errors. Undefined behavior, on the other hand, means that it is up to the compiler writer and system; anything can happen - it can work correctly, it can erase your boot sector, zombie Alan Turing rise and feast on your brains, etc.
For example, using an uninitialized variable like so:
int i;
std::cout << i << std::endl;
on some compilers will give you a pattern like 0xCECECECE in debug builds to help find uninitialized variables. In release builds it might be set to 0 by the compiler, or it might be garbage data.

C++ cin numbers ignores first line?

I've run into a really strange issue. I can reproduce on my win7 laptop as well as an ubuntu machine.
I have a C++ program like so:
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
int main() {
for (int i = 0; i < 9; i++) {
string line;
getline(cin, line);
stringstream ss(line);
for (int j = 0; j < 9; j++) {
int p = 8;
ss >> p;
cout << p;
}
cout << endl;
}
return 0;
}
Now, if i compile it an run it with ./a.out < test.txt where text.txt contains:
1 2 3 4 5 6 7 8 9
2 2 3 4 5 6 7 8 9
3 2 3 4 5 6 7 8 9
4 2 3 4 5 6 7 8 9
5 2 3 4 5 6 7 8 9
6 2 3 4 5 6 7 8 9
7 2 3 4 5 6 7 8 9
8 2 3 4 5 6 7 8 9
9 2 3 4 5 6 7 8 9
It will output (without spaces):
8 8 8 8 8 8 8 8 8
2 2 3 4 5 6 7 8 9
3 2 3 4 5 6 7 8 9
4 2 3 4 5 6 7 8 9
5 2 3 4 5 6 7 8 9
6 2 3 4 5 6 7 8 9
7 2 3 4 5 6 7 8 9
8 2 3 4 5 6 7 8 9
9 2 3 4 5 6 7 8 9
Why is the first line wrong? I've tried reading the first line out of the loop as well.
Also, if I replace ss > p with cin > p I just get an output table full of 8's.
This is not making any sense!!
Okay you guys were right. Some weird stuff as the first character of my input file:
od -c test.txt
0000000 357 273 277 2 0 5 0 0 7 0
0000020 0 6 \n 4 0 0 9 6 0
0000040 0 2 0 \n 0 0 0 0 8
It's a problem with the data (since the code looks OK). Most probably you've saved your text file with UTF-8 encoding with BOM. An UTF-8 BOM is three bytes at the start of the file, and trying to interpret those as a decimal number specification would fail.
Second, third, fourth line etc. OK because you're creating new istringstream object for each line, so not retaining error mode from previous line.
So, fix: save the file without BOM -- assuming the BOM hypothesis is correct.
Cheers & hth.,
Your code seems fine to me, if I were you I'd double check the input file : are you sure there is no empty first line, or some non-numeric character on the beginning of line 1 ?
I suspect you wrote your own getline(), and the bug is there. InputStreams have a getline(char*, int), and I suspect your cramming string.begin() into the first param, and Some Other Number into the latter.
Don't do that.
All your program should be doing is copying the input to the output (given this code and that input). It's not doing that either, even on the lines that "work".
I am seeing a number of Not So Experienced Programmer 'signatures' here.
1) Overly short variable names (outside a for loop counter), "ss" and "p"
2) Magic error number (8), particularly one that doesn't stand out from the data.
3) "using"
1 and 3 both hint at a lack of typing speed, and therefore experience... despite your 1k+ reputation (which is based mostly on asking questions... the situation becomes clearer).
I'd rewrite it something like this:
int curDig;
curLine >> curDig;
if (curLine.good()) {
cout << curDig;
} else {
cout << "FAILED at line: " << lineIdx << " containing: " << line << std::endl;
}
Chances are, you're going to see "FAILED at line: 0 containing: " right out of the gate, due to what I think is a bug in your getline().