This is my answer for a question at Baekjoon.
The question was to write a program that prints exactly same as input. The input can be as big as 100 lines and each line contains at most 100 characters(numbers , alphabet, space). No line starts or ends with a space.
example input)
Hello
nice too meet
ya
example output)
Hello
nice too meet
ya
Below is my code for the question. I've tested all the cases that could happen within my knowledge except 100 lines of 100 characters. It worked for me. But it keeps failing the test. Can anyone please find what the cause is?
#include <iostream>
using namespace std;
int main()
{
char* line[100];
int count=0;
for (int i = 0; cin.getline((line[i]= new char), 100); i++,count++) {
if (cin.eof()) break;
}
for(int i=0; i<count;i++){
cout << line[i] << endl;
}
return 0;
}
Learn the standard library. C++ is all about not re-inventing wheels. There's a buffer called std::ostringstream that will do it all, without all those assumptions about the input. Plus, it will be highly optimized for streaming.
#include <iostream>
#include <sstream>
int main() {
std::ostringstream buffer{};
buffer << std::cin.rdbuf();
std::cout << buffer.str();
return 0;
}
... or (less efficiently), you could use a string as your buffer. Lot's of ways to do this.
#include <string>
#include <iostream>
int main() {
std::string buffer{};
{ char ch;
while (std::cin.get(ch)) buffer.push_back(ch);
}
std::cout << buffer;
return 0;
}
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
CODE-JAM 2010 PROBLEM:
Given a list of space separated words, reverse the order of the words.
INPUT:
The first line of input gives the number of cases, N. N test
cases follow.
OUTPUT:
For each test case, output one line containing "Case #x: "
followed by the list of words in reverse order.
Limits:
N <= 5
INPUT:
3
this is a test
foobar
all your base
OUTPUT:
Case #1: test a is this
Case #2: foobar
Case #3: base your all
#include<iostream.h>
#include<conio.h>
#include<fstream.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
class prog {
char str[50];
public:
void getdata()
{
gets(str);
}
void rev();
void srev();
void display()
{
cout<< str;
}
};
void prog::srev()
{
int i,j,len;
char temp;
len=strlen(str);
for(i=0,j=len-1;i<len/2;i++,j--)
{
temp=str[i];
str[i]=str[j];
str[j]=temp;
}
}
void prog::rev()
{
int i,k=0;
char word[50];
strcat(str," ");
for(i=0;str[i]!='\0';i++)
{
if(str[i]!=' ')
{
word[k]=str[i];
k++;
}
else
{
while(k>0)
{
cout<<word[--k];
}
cout<<str[i];
}
}
}
void main()
{ clrscr();
fstream file;
int n;
cout<<"\n\n\t";
cin>>n;
prog p[10];
file.open("cj.txt",ios::in|ios::out|ios::binary);
for(int i=0;i<n;i++)
{
cout<<"\n\t";
p[i].getdata();
file.write((char*)&p[i],sizeof(p[i]));
}
file.seekg(0);
for(i=0;i<n;i++)
{
cout<<"\n\n\t";
p[i].srev();
p[i].rev();
}
}
I wrote this program in c++98 version, with turbo 3.0 as the IDE. It worked fine giving the desired ouput in the desired limits.
My question is, as C++ has rolled out C++11 Standard, what changes I have to do in my above code?
Also, can anyone provide me some good links to read out about the exact implementations in the libraries, as the changes must be innumerous, at one place?
For a more idiomatic approach, please see Reversing order of words in a sentence. I modified Stefan's answer a little bit:
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
int main()
{
std::string sentence = "Your sentence which contains ten words, two of them numbers";
std::istringstream stream(sentence);
std::vector<std::string> words;
std::copy(std::istream_iterator<std::string>(stream),
std::istream_iterator<std::string>(),
std::back_inserter(words));
std::reverse(words.begin(), words.end());
for ( size_t i(0); i < words.size(); ++i )
{
std::cout << words[i] << " ";
}
std::cout << "\n";
}
Also, since the problem from what I understand specifies a max amount of letters/words that will be given, you can get rid of std::reverse:
words.resize(20); // replace 20 with max amount
std::copy(std::istream_iterator<std::string>(stream),
std::istream_iterator<std::string>(),
words.rbegin());
Two other contrived examples:
std::reverse_copy(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout, " "));
std::copy(words.rbegin(), words.rend(), std::ostream_iterator<std::string>(std::cout, " "));
Your code needs considerable revision to follow C++98. At least offhand, I don't see any reason it would need further revision to follow C++11, though you might be able to make the code a little more readable using some of the new features of C++11.
In C++98/03, I'd probably write the code something like this:
int main() {
int num;
std::cin >> num;
for (int i=0; i<num; i++) {
std::string line;
std::getline(line, std::cin);
std::istringstream in(line);
std::vector<std::string> words((std::istream_iterator<std::string>(in)),
std::istream_iterator<std::string>());
std::copy(words.rbegin(), words.rend(),
std::ostream_iterator<std::string>(std::cout, " "));
}
}
In going to C++11, the primary change I'd make would be to use "uniform initialization":
std::vector<std::string> words{std::istream_iterator<std::string>(in),
std::istream_iterator<std::string>()};
A few people have written code to (for one example) use a range-based for loop in cases like this, so the loop would end up something like:
for (auto i : range(0, num))
I guess if you had a lot of other code that could use this, it might be worthwhile, but I see little point in it for one loop.
#include <iostream>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <string>
#include <iomanip>
#include <fstream>
#include <stdio.h>
using namespace std;
int main()
{
ifstream file;
string filename;
char character;
int letters[153] = {};
cout << "Enter text file name: ";
cin >> filename;
file.open(filename.c_str());
if (! file.is_open())
{
cout << "Error opening file. Check file name. Exiting program." << endl;
exit(0);
}
while (file.peek() != EOF)
{
file >> character;
if(!file.fail())
{
letters[static_cast<int>(character)]++;
}
}
for (int i = 0; i <= 153; i++)
{
if (letters[i] > 0)
{
cout << static_cast<char>(i) << " " << letters[i] << endl;
}
}
exit(0);
}
#endif
Hi everyone, my current code counts the frequency of each letter from a text file. However, it does not count the number of blank spaces. Is there a simple way to printout the number of blank spaces in a .txt file?
Also, how come when I'm trying to access a vector item, I run into a seg fault?
For example, if I use:
cout << " " + letters[i] << endl;, it displays a segfault. Any ideas?
Thank you so much.
By default, iostreams formatted input extraction operations (those using >>) skip past all whitespace characters to get to the first non-whitespace character. Perhaps surprisingly, this includes the extraction operator for char. In order to consider whitespace characters as characters to be processed as usual, you should alter use the noskipws manipulator before processing:
file << std::noskipws;
Don't forget to set it back on later:
file << std::skipws;
What if you're one of those crazy people who wants to make a function that leaves this aspect (or in even all aspects) of the stream state as it was before it exits? Naturally, C++ provides a discouragingly ugly way to achieve this:
std::ios_base::fmtflags old_fmt = file.flags();
file << std::noskipws;
... // Do your thang
file.flags(old_fmt);
I'm only posting this as an alternative way of doing what you're apparently trying. This uses the same lookup table approach you use in your code, but uses an istreambuf_iterator for slurping unformatted (and unfiltered) raw characters out of the stream buffer directly.
#include <iostream>
#include <fstream>
#include <iterator>
#include <climits>
int main(int argc, char *argv[])
{
if (argc < 2)
return EXIT_FAILURE;
std::ifstream inf(argv[1]);
std::istreambuf_iterator<char> it_inf(inf), it_eof;
unsigned int arr[1 << CHAR_BIT] = {};
std::for_each(it_inf, it_eof,
[&arr](char c){ ++arr[static_cast<unsigned int>(c)];});
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);++i)
{
if (std::isprint(i) && arr[i])
std::cout << static_cast<char>(i) << ':' << arr[i] << std::endl;
}
return 0;
}
Executing this on the very source code file itself, (i.e. the code above) generates the following:
:124
#:4
&:3
':2
(:13
):13
*:1
+:4
,:4
/:1
0:3
1:2
2:1
::13
;:10
<:19
=:2
>:7
A:2
B:1
C:1
E:2
F:1
H:1
I:3
L:1
R:2
T:2
U:1
X:1
[:8
]:8
_:10
a:27
b:1
c:19
d:13
e:20
f:15
g:6
h:5
i:42
l:6
m:6
n:22
o:10
p:1
r:37
s:20
t:34
u:10
v:2
z:2
{:4
}:4
Just a different way to do it, but hopefully it is clear that usually the C++ standard library offers up elegant ways to do what you desire if you dig deep enough to find whats in there. Wishing you good luck.
#include<iostream>
using namespace std;
int main(){
char sampleName[30];
char middle;
int i;
cin>>sampleName;
for(i=0;i<30;i++){
if(sampleName[i]=='.'){
middle=sampleName[i-1];
break;
}
}
cout<<middle;
return 0;
}
It doesn't seem to work though when the input has spaces in it. Please. Can anyone help me out?
I am not completely sure what your expected input is, but you may wish to look into std::getline (in conjunction with std::string) to avoid whitespace issues with std::cin >> .... (See here for a relevant discussion.)
So, something of the form
#include <iostream>
#include <string>
int main()
{
std::string sampleName;
char middle;
std::getline(std::cin, sampleName);
for (int i = 0; i < sampleName.size(); i++)
{
if (sampleName[i] == '.')
{
middle = sampleName[i-1];
break;
}
}
std::cout << middle << std::endl;
return 0;
}
may work best. (Click here to test.)
you hav getline function to get in a line with spaces. You are getting wrong output because your program is not taking input with spaces correctly.
What's the most compact way to compute the number of lines of a file?
I need this information to create/initialize a matrix data structure.
Later I have to go through the file again and store the information inside a matrix.
Update: Based on Dave Gamble's. But why this doesn't compile?
Note that the file could be very large. So I try to avoid using container
to save memory.
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
int main ( int arg_count, char *arg_vec[] ) {
if (arg_count !=2 ) {
cerr << "expected one argument" << endl;
return EXIT_FAILURE;
}
string line;
ifstream myfile (arg_vec[1]);
FILE *f=fopen(myfile,"rb");
int c=0,b;
while ((b=fgetc(f))!=EOF) c+=(b==10)?1:0;
fseek(f,0,SEEK_SET);
return 0;
}
I think this might do it...
std::ifstream file(f);
int n = std::count(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), '\n') + 1;
If the reason you need to "go back again" is because you cannot continue without the size, try re-ordering your setup.
That is, read through the file, storing each line in a std::vector<string> or something. Then you have the size, along with the lines in the file:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
int main(void)
{
std::fstream file("main.cpp");
std::vector<std::string> fileData;
// read in each line
std::string dummy;
while (getline(file, dummy))
{
fileData.push_back(dummy);
}
// and size is available, along with the file
// being in memory (faster than hard drive)
size_t fileLines = fileData.size();
std::cout << "Number of lines: " << fileLines << std::endl;
}
Here is a solution without the container:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
int main(void)
{
std::fstream file("main.cpp");
size_t fileLines = 0;
// read in each line
std::string dummy;
while (getline(file, dummy))
{
++fileLines;
}
std::cout << "Number of lines: " << fileLines << std::endl;
}
Though I doubt that's the most efficient way. The benefit of this method was the ability to store the lines in memory as you went.
FILE *f=fopen(filename,"rb");
int c=0,b;while ((b=fgetc(f))!=EOF) c+=(b==10)?1:0;fseek(f,0,SEEK_SET);
Answer in c.
That kind of compact?
#include <stdlib.h>
int main(void) { system("wc -l plainfile.txt"); }
Count the number of instances of '\n'. This works for *nix (\n) and DOS/Windows (\r\n) line endings, but not for old-skool Mac (System 9 or maybe before that), which used just \r. I've never seen a case come up with just \r as line endings, so I wouldn't worry about it unless you know it's going to be an issue.
Edit: If your input is not ASCII, then you could run into encoding problems as well. What's your input look like?
I'm obviously not quite getting the 'end-of-file' concept with C++ as the below program just isn't getting past the "while (cin >> x)" step. Whenever I run it from the command line it just sits there mocking me.
Searching through SO and other places gives a lot of mention to hitting ctrl-z then hitting enter to put through an end-of-file character on windows, but that doesn't seem to be working for me. That makes me assume my problem is elsewhere. Maybe defining x as a string is my mistake? Any suggestions about where I'm going wrong here would be great.
Note: sorry for the lack of comments in the code - the program itself is supposed to take in a series of
words and then spit back out the count for each word.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iomanip>
using std::cin;
using std::cout; using std::endl;
using std::sort;
using std::string; using std::vector;
int main()
{
cout << "Enter a series of words separated by spaces, "
"followed by end-of-file: ";
vector<string> wordList;
string x;
while (cin >> x)
wordList.push_back(x);
typedef vector<string>::size_type vec_sz;
vec_sz size = wordList.size();
if (size == 0) {
cout << endl << "This list appears empty. "
"Please try again." << endl;
return 1;
}
sort(wordList.begin(), wordList.end());
cout << "Your word count is as follows:" << endl;
int wordCount = 1;
for (int i = 0; i != size; i++) {
if (wordList[i] == wordList[i+1]) {
wordCount++;
}
else {
cout << wordList[i] << " " << wordCount << endl;
wordCount = 1;
}
}
return 0;
}
If you're on windows ^Z has to come as the first character after a newline, if you're on a unixy shell then you want to type ^D.
The input portion of your code works. The only real problem I see is with the loop the tries to count up the words:
for (int i = 0; i != size; i++) {
if (wordList[i] == wordList[i+1]) {
The valid subscripts for wordList run from 0 through size-1. In the last iteration of your loop, i=size-1, but then you try to use wordList[i+1], indexing beyond the end of the vector and getting undefined results. If you used wordList.at(i+1) instead, it would throw an exception, quickly telling you more about the problem.
My guess is that what's happening is that you're hitting Control-Z, and it's exiting the input loop, but crashing when it tries to count the words, so when you fix that things will work better in general. If you really can't get past the input loop after fixing the other problem(s?), and you're running under Windows, you might try using F6 instead of entering control-Z -- it seems to be a bit more dependable.
I pretty much always use getline when using cin (particularly when what I want is a string):
istream& std::getline( istream& is, string& s );
So, you'd call getline(cin, x) and it would grab everything up to the newline. You have to wait for the newline for cin to give you anything anyway. So, in that case, your loop would become:
while(getline(cin, x))
wordList.push_back(x);
cin does not accept blank space or line breaks so execution of cin does not complete unless you enter something , here is a test program that gives you what you want
#include "stdafx.h"
#include<iostream>
#include <string>
#include <sstream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string str = "";
while(std::getline(cin, str) && str!="")
{
cout<<"got "<<str<<endl;
}
cout<<"out"<<endl;
cin>>str;
return 0;
}