I'm writing a function that reads line by line from cin and returns when it sees ; character.
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
using namespace std;
int read_cmd(char *cmd)
{
cout << "Please enter a string: \n";
cmd[0]='\0';
while(1){
char currentLine[10000];
currentLine[0]='\0';
cin.getline(currentLine,10000);
if (strcmp(currentLine,";")==0){
break;
}
strcat(cmd, "\n");
strcat(cmd, currentLine);
}
return 0;
}
int main(){
char cmd[1000];
while (1){
read_cmd(cmd);
cout<< cmd << endl;
}
}
I then tested it using text fed from another file via pipe.
./read_cmd < test_file
contents of test_file:
line 1
line 2
;
This outputs results just fine, however it gives me a segmentation fault at the end. Is there a way for cin to check if it's coming across an EOF and terminates?
To detect the EOF you should use something like:
while (cin.good() && !cin.eof())
{
// Read the file
}
See the documentation for cin, in particular the good() (for error checking) and eof() member functions.
In particular this example might be helpful.
I would highly suggest the use of the string object for something like this, that way you're not wasting space, as well as ensuring that you have enouch space. You can also do it without a loop.
string currentLine;
getline(cin, currentLine, ';');
Now, if you need to get just the last line with has the semi-colon, a loop is necessary, but still you can do it at little more easily.
string currentLine;
while(getline(cin, currentLine)){
if(currentLine.find(";") != string::npos){
break;
}
}
Use strings to pass things around as well. There's always the .clear() method as well that any string has for easy emptying.
string getline
string Object
Related
I am a beginner and I'm trying to limit the user to input a single character only, I do aware of using cin.get(char) and it will only read one character from the input, but I don't want the other characters be left in buffer. Here is a sample of my code using EOF, but it doesn't seem to work.
#include <iostream>
#include <sstream>
using namespace std;
string line;
char category;
int main()
{
while (getline (cin, line))
{
if (line.size() == 1)
{
stringstream str(line);
if (str >> category)
{
if (str.eof())
break;
}
}
cout << "Please enter single character only\n";
}
}
I have used this for digit inputs and the eof works fine.
But for the char category the str.eof() seems to be false.
Can someone explain? Thanks in advance.
The eof flag is only set if you read try to read past the end of the stream. If str >> category read past the end of the stream, if (str >> category) would have evaluated false and not entered the loop to test (str.eof()). If there was one character on the line you would have to attempt to read two characters to trigger eof. Reading two characters is far more effort than testing the length of line to see how long it is.
while (getline (cin, line)) got the whole line from the console. If you don't consume it in the stringstream it doesn't matter, that stuff is gone is gone from cin when you loop back around in the while.
In fact, the stringstream isn't doing you any favours. Once you've confirmed the length of the line that was read, you can just use line[0].
#include <iostream>
using namespace std;
int main()
{
string line; // no point to these being global.
char category;
while (getline(cin, line))
{
if (line.size() == 1)
{
//do stuff with line[0];
}
else // need to put the fail case in an else or it runs every time.
// Not very helpful, an error message that prints when the error
// didn't happen.
{
cout << "Please enter single character only\n";
}
}
}
I want get from user word and put into place in file where is certian word.
I have problem with getline.
In new file I don't have any new line.
When I add Newline to string which I write to file, this line is read two times and writeto file to times (I think that bcoz I saw this newfile)
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string contain_of_file,bufor,word,empty=" ",new_line="\n";
string conection;
string::size_type position;
cout<<"Give a word";
cin>>word;
ifstream NewFile;
ofstream Nowy1;
Nowy1.open("tekstpa.txt", ios::app);
NewFile.open("plik1.txt");
while(NewFile.good())
{
getline(NewFile, contain_of_file);
cout<<contain_of_file;
position=contain_of_file.find("Zuzia");
if(position!=string::npos)
{
conection=contain_of_file+empty+word+new_line;
Nowy1<<conection;
}
Nowy1<<contain_of_file;
}
Nowy1.close();
NewFile.close();
cin.get();
return 0;
}
The problem here is not your reading. directly, but about your loop.
Do not loop while (stream.good()) or while (!stream.eof()). This is because the eofbit flag is not set until after you try to read from beyond the file. This means that the loop will iterate one extra time, and you try to read from the file but the std::getline call will fails but you don't notice it and just continue as if nothing happened.
Instead do
while (std::getline(NewFile, contain_of_file)) { ... }
And an unrelated tip: The variable conection is not needed, you can instead do just
Nowy1 << contain_of_file << ' ' << word << '\n';
I've been trying to read some information in from a .txt file in C++ but it's not all working like I expect. Here is some example code:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char words[255];
int value = 0;
ifstream input_stream("test.txt");
input_stream >> value;
input_stream.getline(words, 256);
cout << value << endl;
cout << words << endl;
}
And test.txt contains:
1234
WordOne WordTwo
What I expect is for the code to print the two lines contained in the text file, but instead I just get:
1234
I've been reading about getline and istream but can't seem to find any solutions so any help would be appreciated.
Thanks
The newline character remains in the input stream after the read of the integer:
// Always check result to ensure variables correctly assigned a value.
if (input_stream >> value)
{
}
Then, the call to getline() reads the newline character and stops, producing an empty string. To correct, consume the newline character before calling getline() (options include using getline() or ignore()).
Note there is a version std::getline() that accepts a std::string as its argument to avoid using a fixed sized array of char, which is used incorrectly in the posted code.
ifstream's getline method gathers input until one of two options is hit. Either a terminating character or the size passed in is reached. In your case, the newline terminator is encountered before the size is reached.
Use another getline to retrieve the second line of text.
Reference
The problem you are seeing is that the first newline after 1234 is not consumed by input_stream>>(int); so the next getline only reads to the end of that file.
This is a very constructed scenario, commonly found in schoolwork. The more common scenario when reading a textfile is to consider the entire file as linebased text.
In this case the more convenient
string line;
while( std::getline( input_stream, line ) ){
}
is appropriate, and way less error prone.
The textfile would commonly have a predefined format. Perhaps name = value lines, and are parsed as such after the line is read from the file.
Here is a somewhat corrected version of your original code:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char words[256]; // was 255
int value = 0;
ifstream input_stream("test.txt");
input_stream >> value;
input_stream.ignore(); // skip '\n'
input_stream.getline(words, 256);
cout << value << endl;
cout << words << endl;
}
Also, I would advise you to use a string instead of a char[] and use the other getline function.
Somehow when I run this code and it comes to inputting strings, the first string where i=0 is being skipped and it starts entering strings from A[1]. So I end up with A[0] filled with random stuff from memory. Can someone please point at the problem?
cin>>s;
char** A;
A = new char *[s];
cout<<"now please fill the strings"<<endl;
for (int i=0;i<s;i++)
{
A[i] = new char[100];
cout<<"string "<<i<<": ";
gets(A[i]);
}
That code is horrible. Here's how it should look like in real C++:
#include <string>
#include <iostream>
#include <vector>
int main()
{
std::cout << "Please start entering lines. A blank line or "
<< "EOF (Ctrl-D) will terminate the input.\n";
std::vector<std::string> lines;
for (std::string line; std::getline(std::cin, line) && !line.empty(); )
{
lines.push_back(line);
}
std::cout << "Thank you, goodbye.\n";
}
Note the absence of any pointers or new expressions.
If you like you can add a little prompt print by adding std::cout << "> " && at the beginning of the conditional check in the for loop.
Probably because you're using gets()... never use gets()
Use fgets() instead.
gets vs fgets
The problem is that cin>>s; just picks up the number you want and leaves a \n (newline from the enter press) on stdin that gets() picks up in the first iteration. This is not the nicest way to fix it, but to prove it write this line after that line:
int a = fgetc(stdin);
Check out a afterwards to confirm it has a newline.
Well, you probably get an empty string: when reading s you use formatted input which stops as soon as a non-digit is encountered, e.g., the newline used to indicate its input is finished. gets(), thus, immediately finds a newline, terminating the first string read.
That said, you shall never use gets(): It is a primary security problem and the root cause of many potential attack! You should, instead, use fgets() or, better, yet, std::getline() together with std::strings and a std::vector<std::string> >. Aslo, you should always verify that the attempt to input was successful:
if ((std::cin >> s).ignore(std::numeric_limits<std::streamsize>::max(), `\n`)) {
std::string line;
for (int i(0); i != s && std::getline(std::cin, line); ) {
A.push_back(line);
}
}
i have a little problem on writing the string into a file,
How can i write the string into the file and able to view it as ascii text?
because i am able to do that when i set the default value for str but not when i enter a str data
Thanks.
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
int main()
{
fstream out("G://Test.txt");
if(!out) {
cout << "Cannot open output file.\n";
return 1;
}
char str[200];
cout << "Enter Customers data seperate by tab\n";
cin >> str;
cin.ignore();
out.write(str, strlen(str));
out.seekp(0 ,ios::end);
out.close();
return 0;
}
Please use std::string:
#include <string>
std::string str;
std::getline(cin, str);
cout << str;
I'm not sure what the exact problem in your case was, but >> only reads up to the first separator (which is whitespace); getline will read the entire line.
Just note that >> operator will read 1 word.
std::string word;
std::cin >> word; // reads one space seporated word.
// Ignores any initial space. Then read
// into 'word' all character upto (but not including)
// the first space character (the space is gone.
// Note. Space => White Space (' ', '\t', '\v' etc...)
You're working at the wrong level of abstraction. Also, there is no need to seekp to the end of the file before closing the file.
You want to read a string and write a string. As Pavel Minaev has said, this is directly supported via std::string and std::fstream:
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::ofstream out("G:\\Test.txt");
if(!out) {
std::cout << "Cannot open output file.\n";
return 1;
}
std::cout << "Enter Customer's data seperated by tab\n";
std::string buffer;
std::getline(std::cin, buffer);
out << buffer;
return 0;
}
If you want to write C, use C. Otherwise, take advantage of the language you're using.
I can't believe no one found the problem. The problem was that you were using strlen on a string that wasn't terminated with a null character. strlen will keep iterating until it finds a zero-byte, and an incorrect string length might be returned (or the program might crash - it's Undefined Behavior, who knows?).
The answer is to zero-initialize your string:
char str[200] = {0};
Supplying your own string as the value of str works because those in-memory strings are null-terminated.