c++ Reading in integers from a .txt file to a stack - c++

This is so stupid. I've been stuck literally for an hour trying to read in a .txt file of numbers that are separated by a single whitespace. The while loops only gets executed once for some reason!
#include <iostream>
#include <string>
#include <fstream>
#include <stack>
using namespace std;
int main(int argc, char* argv[])
{
string line;
string str(argv[1]);
ifstream myfile((str).c_str());
int num;
stack<int> x;
while (myfile >> num);
{
x.push(num);
}
return(0);
}

Hmm, look at this line more closely:
while (myfile >> num);
Eventually, you'll notice the semi-colon. The compiler thinks this means you want a loop that does nothing (the semi-colon here indicates a single, empty statement). So, the loop reads in all the numbers, but does nothing with them.
The next section is interpreted separately as a statement in its own scope (denoted by the braces), to be executed after the loop:
{
x.push(num);
}
All that does is push the last number read onto the stack, leading you to think the loop only executes once.
Remove the ; and you're OK! Once bitten by this, you'll never forget ;-)
On an unrelated note, it's a bit silly to take argv[1] (a C-style string), put it into a string object, then use c_str() to turn that back into a C-string for the ifstream constructor. Just use argv[1] directly, since you're not doing anything else with it. Also, it would be a good idea to check argc first and make sure that a filename was passed in. Finally, you should check that the file was successfully opened instead of assuming it -- at the very least make your assumption explicit with an assert(myfile.is_open());. Oh, and you don't use the line variable at all.

Related

second getline or other input functions doesnt work when i exceed the array size in input for first getline()

#include <iostream>
#include <string.h>
#include<stdio.h>
using namespace std;
int main()
{
char d,a[9],e[9];
cin.getline(a,9);
cin.getline(e,9);
cin>>d;
puts(a);
puts(e);
cout<<d<<endl;
return 0}
when i enter "hey every one" on the output screen, puts(e) prints a blank line and d prints a random character.second getline function and cinfunction is not working because of first getline. Thanks in advance.
You should read some documentation for the stuff you use:
After constructing and checking the sentry object, extracts characters from *this and stores them in successive locations of the array whose first element is pointed to by s, until any of the following occurs (tested in the order shown):
- [...]
- count-1 characters have been extracted (in which case setstate(failbit) is executed).
(Emphasize mine)
So the first getline fails if the input is too long and thus leaves std::cin in a bad (i.e. unreadable) state. This makes all successive input operations fail immediately.
Remark: To avoid tons of ugly trouble, you should avoid using C-style strings and the "kind of C-style" member-getline and just use std::string and the non-member std::getline instead.
When you use
cin.getline();
and when you press Enter after entering the string, that enter goes into the next string.
In order to prevent it, use
cin.ignore();
It ignores the Enter and prevents it from entering into another string.
Here is your modified code:
#include<iostream>
#include <cstring>
using namespace std;
int main()
{
char d,a[9],e[9];
cout<<"String:"<<endl;
cin.getline(a,9);
cin.ignore();
cout<<"String:"<<endl;
cin.getline(e,9);
cin>>d;
cout<<a;
cout<<e;
cout<<d<<endl;
return 0;
}

read and extract informations from file c++

I am trying to find a solution for the error that the c++ compiler (codeblocks) keeps showing to me,I searched for answers on the net but none of them seemed to be helpful.
I have a txt file in which there are numbers,each of them is written in a line.
What i want is to read each number(line by line)and store it in a variable after converting it from string to float.
This my code
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
float z;
int j=0;
stringstream s;
const ifstream fich1;
fich1.open("test.txt",ios::in);
if(!fich1)
{
cerr<<"could not open the file";
EXIT_FAILURE;
};
else const string ligne1;
while((!fich1.eof())
{
if(j!=i)
{
j++;
getline(fich1,l1); // the first error is: no matching function for call to ‘getline(const ifstream&, const string&)
else if(j == i)
{
fich1>>s; // the second error is: ambiguous overload for ‘operator>>’ (operand types are ‘const ifstream {aka const std::basic_ifstream<char>}’ and ‘std::stringstream {aka std::basic_stringstream<char>}’)
z=(float)s; // I couldn't find a clear answer to convert from string to float
}
}
if anyone wants to ask any question about the code to make it clearer may ask it please,I am waiting for your answers as well as your questions :)
After the edit, I am able to read some code, but still I am suggesting the example I have below, since I am see scary things, like an EOF inside a loop!
Oh also, if you have C++11 support, then you could use std::stof.
You could try this (since your post is not readable), which reads a file line by line and stores every float number in a vector:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
int main() {
std::vector<float> v;
std::string rec_file = "test.txt";
std::string line;
std::ifstream myfile(rec_file.c_str());
if(myfile.is_open()) {
while(std::getline(myfile,line)) {
if(!line.empty())
v.push_back(atof(line.c_str()));
}
myfile.close();
} else {
std::cerr << "Unable to open file";
}
for(unsigned int i = 0; i < v.size(); ++i)
std::cout << v[i] << std::endl;
return 0;
}
with the test.txt to be:
1.2
2.3
3.4
4.5
5.6
6.7
and the output:
1.2
2.3
3.4
4.5
5.6
6.7
Your ifstream shouldn't be constant, as getline alters the ifstream.
To convert from char array to float use atof(chararray)
To convert from string to float you could use atof(string.cstr())
You cannot use const here. But that's not your only problem.
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
Looks good.
float z;
int j=0;
stringstream s;
There should be some int main() { here, because that is the function called by the runtime when a C++ executable starts. This isn't Bash or Perl where execution simply picks up at the first statement.
And you either need to write using namespace std; or prefix identifiers like stringstream as std::stringstream.
const ifstream fich1;
This won't work. ifstream must not be declared const. (This is actually the explanation for the errors you encountered, but you made many more.)
An input file stream is an object with complex inner state, like where in the file you're currently at, error flags etc.; this inner state is changing so const ifstream simply won't work.
fich1.open("test.txt",ios::in);
This can't work either due to const, just like all the other operations on fich1 you're doing further down.
if(!fich1)
{ cerr<<"could not open the file";
EXIT_FAILURE;
};
EXIT_FAILURE is a symbolic constant for a return value. As-is, you could just as well have written 0;. If you expected this to end your program, you're wrong.
;
The semicolon ends the if.
else
Since the if has ended, this is a syntax error.
const string ligne1;
If you declare a string const, you cannot assign to it. Besides, even if the else were correct, that semicolon would have ended the else, because you didn't add braces (as you should always do, even with one-line blocks, because it's so easy to make mistakes otherwise).
The way the code continues, I very much doubt this was your intention. (Some discipline with the indenting makes this kind of mistakes really easy to spot.)
while((!fich1.eof())
How to read until EOF from cin.
{ if(j!=i)
{j++;
Do some proper indenting, will you? Besides, no i has been declared at this point.
getline(fich1,l1);
I assume l1 is the string you declared earlier as ligne1. (Since that happened inside the else, ligne1 is no longer in scope, but I'll let that one pass since you obviously intended the while to be inside the else block.)
Anyway, this can't work because both your ifstream and your string are constant, i.e. cannot be changed. This does not make sense, and thus getline() was not defined for const parameters.
else if(j == i)
Since you didn't close the brace of the if statement above, this is a syntax error as well. Again, proper indenting discipline would have made this immediately obvious.
{ fich1>>s;
I very much doubt there exists an operator>>() for const ifstream, so I am not surprised you get an error here.
z=(float)s;
You're trying to cast (C style, too...) a stringstream object to a float number? What do you expect the result might be? It will definitely not be the 3.14 or whatever you've written into test.txt...
}
}
Lost track of your braces. This code is FUBAR, I didn't even check if it makes sense semantically once all the errors are fixed, and I suspect you're pulling some elaborate troll prank here. If that isn't the case, I suggest you take another good look at whatever textbook you're using to learn C++, because you got a good many things very wrong.
Purely style-related advice: fich1, ligne1... don't use localized (non-English) identifiers. It just adds another problem when communicating about your code. (And this is coming from a non-native English speaker.)

strcpy_s in c++

I am new to C++ . I am writing following simple code. I wanted to pass the character[40] into a function and then get the same as output.
If i put a debug at following point.
strcpy_s(x,100,tester);
But it only takes "This" if i write "This is sent at the output". Can anyone please point out what am i missing and whats the reason for only accepting few characters.
// BUSTesting.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include "resource.h"
int testFunction(char* tester);
int _tmain()
{
char m[40];
std::cin>>m;
testFunction(m);
}
int testFunction(char* tester)
{
char x[100] ;
memset(x,100,sizeof(x));
strcpy_s(x,100,tester);
std::cout<<x;
return 0;
}
operator>> will stop consuming input at first whitespace character. An alternative would be to use cin.getline() to prevent processing of input due to whitespace.
Note to initialize an array and avoid memset():
char x[100] = "";
Recommend std::string and std::getline() which avoids specifying a maximum number of characters to read from the input stream (avoiding potential buffer overrun problems with fixed sized arrays).
Change this: std::cin >> m; to this cin.getline(m, 39);
cin >> x doesn't get all line characters until end-line when there is a white-space (space, tab, ...) in the input.
Since you are using C++, it is better to use std::string class instead of old C-style strings.
std::cin>>m probably breaks the string on a space for some reason. Break with a debugger and check m's content. If it's only this, you've found the problem.

Length of a char array

I have the code like this:
#include <iostream.h>
#include <fstream.h>
void main()
{
char dir[25], output[10],temp[10];
cout<<"Enter file: ";
cin.getline(dir,25); //like C:\input.txt
ifstream input(dir,ios::in);
input.getline(output,'\eof');
int num = sizeof(output);
ofstream out("D:\\size.txt",ios::out);
out<<num;
}
I want to print the length of the output. But it always returns the number 10 (the given length) even if the input file has only 2 letters ( Like just "ab"). I've also used strlen(output) but nothing changed. How do I only get the used length of array?
I'm using VS C++ 6.0
sizeof operator on array gives you size allocated for the array, which is 10.
You need to use strlen() to know length occupied inside the array, but you need to make sure the array is null terminated.
With C++ better alternative is to simple use: std::string instead of the character array. Then you can simply use std::string::size() to get the size.
sizeof always prints the defined size of an object based on its type, not anything like the length of a string.
At least by current standards, your code has some pretty serious problems. It looks like it was written for a 1993 compiler running on MS-DOS, or something on that order. With a current compiler, the C++ headers shouldn't have .h on the end, among other things.
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::string dir, output, temp;
std::cout<<"Enter file: ";
std::getline(cin, dir); //like C:\input.txt
std::ifstream input(dir.c_str());
std::getline(input, output);
std::ofstream out("D:\\size.txt");
out<<output.size();
}
The getline that you are using is an unformatted input function so you can retrieve the number of characters extracted with input.gcount().
Note that \e is not a standard escape sequence and the character constant \eof almost certainly doesn't do what you think it does. If you don't want to recognise any delimiter you should use read, not getline, passing the size of your buffer so that you don't overflow it.

Streaming output to save things

I would like to << stream to save all inputs from console into a file
Here is how I tried
ofstream of("file.txt");
while(1)
{
string str;
cin>>str;
of<<str;
}
I don't see the non-English characters in the file (Edit: I mean they are Japanese, Chinese or Korean etc)
You could stream char by char. Then it would be a true binary copy.
ofstream of("file.txt");
while(1)
{
char c;
cin>>c;
of<<c;
}
Streaming using the formatted extraction operator is a poor choice. Specifically, it will consume all of the white space.
If it were me, I would copy using std::getline or istream::rdbuf:
std::getline:
// Copy standard input to named file, one line at a time.
#include <iostream>
#include <fstream>
int main (int argc, char **argv) {
std::string s;
std::ofstream of(argv[1]);
while(std::getline(std::cin, s)) {
of << s << "\n";
}
}
istream::rdbuf:
// Copy entire standard input stream to named file in one go
#include <iostream>
#include <fstream>
int main (int argc, char **argv) {
std::ofstream(argv[1]) << std::cin.rdbuf();
}
Just a couple of points as a starter:
ofstream of("file.txt");
If you want to see Japanese, Chinese or Korean character you should not be using an ofstream here. You want a stream that writes wide characters: a std::wofstream. You will also haveendow that stream with a locale. See Why does wide file-stream in C++ narrow written data by default? for details.
Another point: You apparently are have a using namespace std;. You can find many questions here at Stack Overflow that indicate that this is a bad idea. Typing those extra five characters isn't very hard, it avoids problems with names from the standard library polluting your namespace, and it makes the code clearer.
while(1)
Your loop doesn't have any break statements to escape the loop, so this plus the while (1) means your program will never stop. It is just going to keep on going and going and going and going. You want it to stop (or should want it to stop) on encountering an error or end of file in the input stream.
A better approach is to use a construct such as
while (std::getline (std::cin, s))
to control the loop (except you need to use something special to get wide characters).