Reading whole file into std::string

I have been using this:

1
2
std::ifstream in("name.txt");
std::string s((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());


The file I am doing this on is roughly 25 000 characters (including newlines that I need). Is this the best way to do this?
Also, I do not need to edit the string.

EDIT: Code corrected. Thank you Smac89
Last edited on
Should be:

std::string s((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());

right?

I typed it into google and the method you are using seems to be the best way to do this. Here is another site which examines several other methods for accomplishing the same thing:
http://insanecoding.blogspot.ca/2011/11/how-to-read-in-file-in-c.html

Also I usually have this at the beginning of main:
std::ios_base::sync_with_stdio(0);

This is to turn off synchronizing with compatible iostream and stdio objects so they can act independent of each other (Speed gain? Time it).
Thank you, I will time it.
Wow, there is actually a speed loss. The larger program I made was a solution to the USACO Calf Flac problem. The code is given below, as well as the times take for the different test cases.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
LANG: C++
PROG: calfflac
*/

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

//HELPER FUNCTIONS

bool isLetter(char c) {
	if((c>='a' && c<='z') || (c>='A' && c<='Z')) {
		return(true);
	} else {
		return(false);
	}
}

char toCaps(char c) {
	if(c>='a' && c<='z') {
		return(c-32);
	} else {
		return(c);
	}
}

int main() {
	//INPUT AND OUTPUT
	ifstream in("calfflac.in");
	ofstream out("calfflac.out");

	//std::ios_base::sync_with_stdio(0);  //Test with timing
	std::string s((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
	
	/*
	max=-1
	start=end=0
	
	for letter in s:
		cstart=cend=letter(pos)
		//odd
		left=right=letter(pos)
		while(--left>=0 && ++right<s.length()):
			while(!isLetter(s[left]) && left>0) --left;
			while(!isLetter(s[right]) && right<s.length()-1) ++right;
			if(s[left]==s[right]):
				cstart=left;
				cend=right;
			else:
				break;
		
		if(cend-cstart>max):
			start=cstart
			end=cend;
	*/

	int max=-1, start=0, end=0;
	
	for(int i=0; i<s.length(); ++i) {
		if(!isLetter(s[i])) continue;
		{//odd
		int cstart=i, cend=i, cmax=1, left=i, right=i;
		while(--left>=0 && ++right<s.length()) {
			while(!isLetter(s[left]) && left>0) --left;
			while(!isLetter(s[right]) && right<s.length()-1) ++right;
			if(toCaps(s[left])==toCaps(s[right])) {
				cstart=left;
				cend=right;
				cmax+=2;
			} else {
				break;
			}
		}
		if(cmax>max) {
			start=cstart;
			end=cend;
			max=cmax;
		}
		}
		{//even
		int cstart=i, cend=i+1, cmax=0, left=i, right=i+1;
		do {
			while(!isLetter(s[left]) && left>0) --left;
			while(!isLetter(s[right]) && right<s.length()-1) ++right;
			if(toCaps(s[left])==toCaps(s[right])) {
				cstart=left;
				cend=right;
				cmax+=2;
			} else {
				break;
			}
		} while(--left>=0 && ++right<s.length());
		if(cmax>max) {
			start=cstart;
			end=cend;
			max=cmax;
		}
		}
	}
	
	out<<max<<'\n';
	for(int i=start; i<=end; ++i) {
		out<<s[i];
	}
	out<<'\n';
	return(0);
}		


Without line 34:
Executing...
   Test 1: TEST OK [0.000 secs, 3500 KB]
   Test 2: TEST OK [0.000 secs, 3500 KB]
   Test 3: TEST OK [0.000 secs, 3500 KB]
   Test 4: TEST OK [0.000 secs, 3500 KB]
   Test 5: TEST OK [0.000 secs, 3500 KB]
   Test 6: TEST OK [0.000 secs, 3500 KB]
   Test 7: TEST OK [0.000 secs, 3500 KB]
   Test 8: TEST OK [0.162 secs, 3500 KB]


With line 34:
Executing...
   Test 1: TEST OK [0.000 secs, 3636 KB]
   Test 2: TEST OK [0.000 secs, 3636 KB]
   Test 3: TEST OK [0.011 secs, 3636 KB]
   Test 4: TEST OK [0.000 secs, 3636 KB]
   Test 5: TEST OK [0.011 secs, 3636 KB]
   Test 6: TEST OK [0.011 secs, 3636 KB]
   Test 7: TEST OK [0.000 secs, 3636 KB]
   Test 8: TEST OK [0.173 secs, 3636 KB]
Wow, there is actually a speed loss.


No, it isn't. Those times are close enough to each other to be well within any margin of error in reporting (in fact it looks like the granularity of the clock is 11 milliseconds since all the times differ by exactly that much.)

So the change had no effect on your program, which one would expect given you don't use stdio at all.
@cire Thank you for the observations. How would one turn of synchronisation in my program, or is it not possible?
How would one turn of synchronisation in my program, or is it not possible?


You've already done so, and it had no effect, because
cire wrote:
you don't use stdio at all.
Doesn't that code read one char at a time from a file stream?

I would have thought that you needed to resize the string, then use read() to fill the string.
Topic archived. No new replies allowed.