I am reading text from a text file and need to know the number of characters in the file in total. I thought this should work but it always seems to be overcounting. For example I typed this into my text file:
thisisatestthisisa
thisisa
And the program returned a total of 32.
#include <iostream>
#include <fstream>
#include <string>
#include <ostream>
using namespace std;
int main() {
fstream inFile;
string inputString;
inFile.open("text.txt", ios::in);
unsigned int total = 0;
if (inFile) {
while (inFile)
{
getline(inFile, inputString);
unsigned int tempStringLength = inputString.length();
total += tempStringLength;
}
cout << "total is: " << total << endl;
}
else {
cerr << "Unable to open file text.txt";
exit(1);
}
return 0;
}
You are double-counting the last line in the file.
Because you are using while(inFile) instead of while(getline(inFile, inputString)) the stream's state is not invalidated until the call to getline(...):
Walking through the loop will make this obvious:
Iteration 1:
unsigned int total = 0;
//...
while (inFile) //True
{
getline(inFile, inputString); //inFile: True, inputString: thisisatestthisisa
unsigned int tempStringLength = inputString.length(); //18
total += tempStringLength; //18
}
//...
Iteration 2:
//...
while (inFile) //True
{
getline(inFile, inputString); //inFile: True, inputString: thisisa
unsigned int tempStringLength = inputString.length(); //7
total += tempStringLength; //25
}
//...
Iteration 3:
//...
while (inFile) //True
{
getline(inFile, inputString); //inFile: EOF, inputString: thisisa (not modified)
unsigned int tempStringLength = inputString.length(); //7
total += tempStringLength; //32
}
//...
inFile now returns false because the EOF was reached and your loop terminates. Printing 32 as the length.
Long story short: Don't use the file state as a loop terminator. Use the actual read, either getline or operator>> depending on the situation.
Related
I am trying to put the values from the vector into the int.
Given vector :'1','0','1','1','1','0','1','1','1','0','1','1','1','0','1','1' :
Expected output (binary representation for the variable out):
00000000000000001011101110111011.
However, I am getting the following output:
10111011101110110000000000000000
Notice: the insertion begun at the 16bit from right end instead of beginning from the leftmost bit
#include<vector>
#include<iostream>
int main() {
std::vector<unsigned char> test = {'1','0','1','1','1','0','1','1','1','0','1','1','1','0','1','1'};
std::vector<unsigned int> out(1);
int j = 0;
for (int i =0; i < test.size(); i++) {
out[j] = out[j] << 1;
if (test[i] == '1') {out[j] |=0x1;}
}
j++;
for (int p = 0; p < j; p++) {
for (int k = 0; k<32; k++ ) {
std::cout << !!((out[p]<<k)&0x8000);
}
std::cout << std::endl;
}
std::cout << "Size Of:" << sizeof(int);
return 0;
}
The reason why this happens is that you are using a wrong constant for the mask: 0x8000 has its 16-bit set, while you probably meant to use 0x80000000 with the 32-nd bit set. To avoid mistakes like that it's best to construct masks with shifts, for example
(1 << 31)
This expression is evaluated at compile time, so the result is the same as if you computed the constant yourself.
Note that both 0x8000 and 0x80000000 constants are system-dependent. Moreover, 0x80000000 assumes 32-bit int, which is not guaranteed.
A better approach would be shifting the number right instead of left, and masking with 1.
The block of code creating out[j] works just fine.
Your problem is in the output block, due to use of 0x8000. Whenever k >= 16, the low 16 bits will be zero, guaranteeing that 0x8000 is zero.
Your code seems overly complicated to me. Here's my version of a C program that transforms a string of 1's and 0's into an int and one going from int to string.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv);
int main (int argc, char **argv) {
char str [] = "1010101010101010";
int x;
int out;
for (x=0;x<16;x++) {
if (str[x] == '1') {
out |= (1 << x);
}
}
printf("%d", out) ;
}
and
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv);
int main (int argc, char **argv) {
char str [] = "1010101010101010";
int in = 21845;
char out[17] = {0};
for (x=0;x<16;x++) {
if (in & (1<<x)) {
out[x] = '1';
}
else {
out[x] = '0';
}
}
printf("%s", out) ;
}
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <cstdlib>
//These two functions work fine
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
if(!item.empty())
elems.push_back(item);
}
return elems;
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
//I think this function is where the problem is
std::string& singleSplit(const std::string* s, char delim='\0'){
static std::string input=*s;
static std::stringstream ss(*s);
if(input!=*s){ss.str(*s);input=*s;}
std::string item;
if (std::getline(ss, item, delim)&&!item.empty())
{std::cout<<item<<std::endl;return item;}
}
void setIntFrames(std::vector<std::string>& frames, std::vector<uint16_t>* Start, std::vector<uint16_t>* End)
{
for(int i=0; i<frames.size(); i++)
{
Start->push_back(std::atoi((singleSplit(&frames[i],'-').c_str())));
End->push_back(std::atoi((singleSplit(&frames[i],'\0').c_str())));
}//this loop works fine the first time it passes, but the second time it just pushes back 0's into my Start and End vectors
}
int main()
{
std::string x="0000-1200,1201-2359";//sample string of what alloted time frames in a day would look like
std::vector<std::string>timeFrames(split(x,','));
std::vector<uint16_t>startTimes; std::vector<uint16_t>endTimes;
setIntFrames(timeFrames, &startTimes, &endTimes);
std::cout<<startTimes[1]<<std::endl<<endTimes[1];
//setIntFrames() didn't set these correctly, I don't know why
return 0;
}
I'm trying to make a simple scheduling program. I'm dealing with converting string x inside of main() into to arrays(vectors in this case) of start and end times. The way I'm trying to do it is first to split the original string into multiple strings(delimited by ',') then placed into the vector timeFrames. The next step would be to split those smaller strings, turn them to ints, and place them into either the startTimes vector or endTimes vector. I use setIntFrames for this step but I don't understand why it only works to set the first timeFrame.
I'm pretty sure the problems lies in my singleSplit() function, but I don't understand getline and stringstream enough to fix this. Any help is appreciated.
This works for me. I changed pass arguments in as references and then pushing them back after use.
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <cstdlib>
//These two functions work fine
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
if(!item.empty())
elems.push_back(item);
}
return elems;
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
//I think this function is where the problem is
void singleSplit(const std::string& s, char delim, std::string& first, std::string& second){
std::stringstream ss(s);
if (std::getline(ss, first, delim)){
std::cout << "Found:" << first << '\n';
}
if (std::getline(ss, second)){
std::cout << "Found:" << second << '\n';
}
}
void setIntFrames(std::vector<std::string>& frames, std::vector<uint16_t>& Start, std::vector<uint16_t>& End)
{
std::string first, second;
for(int i=0; i<frames.size(); i++)
{
std::cout << frames[i] << '\n';
singleSplit(frames[i], '-', first, second);
Start.push_back(std::atoi(first.c_str()));
End.push_back(std::atoi(second.c_str()));
}//this loop works fine the first time it passes, but the second time it just pushes back 0's into my Start and End vectors
}
int main()
{
std::string x="0000-1200,1201-2359";//sample string of what alloted time frames in a day would look like
std::vector<std::string>timeFrames(split(x,','));
std::vector<uint16_t>startTimes; std::vector<uint16_t>endTimes;
setIntFrames(timeFrames, startTimes, endTimes);
// std::cout<<startTimes[1]<<std::endl<<endTimes[1];
for (int i = 0; i < startTimes.size(); ++i){
std::cout << i << ':' << startTimes[i] << '\t' << endTimes[i] << '\n';
}
//setIntFrames() didn't set these correctly, I don't know why
return 0;
}
The output looks like this:
$ a.out
0000-1200
Found:0000
Found:1200
1201-2359
Found:1201
Found:2359
0:0 1200
1:1201 2359
I have successfully designed the algorithm to print all the permutations with the repetition of numbers. But the algorithm which I have designed has a flaw. It works only if the chars of the string are unique.
Can someone help me out in extending the algorithm for the case where chars of the string may not be unique..
My code so far :
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<iostream>
using namespace std;
void _perm(char *arr, char*result, int index)
{
static int count = 1;
if (index == strlen(arr))
{
cout << count++ << ". " << result << endl;
return;
}
for (int i = 0; i < strlen(arr); i++)
{
result[index] = arr[i];
_perm(arr, result, index + 1);
}
}
int compare(const void *a, const void *b)
{
return (*(char*)a - *(char*)b);
}
void perm(char *arr)
{
int n = strlen(arr);
if (n == 0)
return;
qsort(arr, n, sizeof(char), compare);
char *data = new char[n];
_perm(arr, data, 0);
free(data);
return;
}
int main()
{
char arr[] = "BACD";
perm(arr);
return 0;
}
I am printing the output strings in lexicographically sorted way.
I am referring to the example.3 from this page.
http://www.vitutor.com/statistics/combinatorics/permutations_repetition.html
Thanks.
Your code doesn't print permutations, but four draws from the string pool with repetition. It will produce 4^4 == 256 combinations, one of which is "AAAA".
The code Karnuakar linked to will give you permutations of a string, but without distinguishing between the multiple occurrences of certain letters. You need some means to prevent recursing with the same letter in each recursion step. In C++, this can be done with a set.
The example code below uses a typical C string, but uses the terminating '\0' to detect the end. The C-string functions from <cstring> are not needed. The output will not be sorted unless the original string was sorted.
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
void perm(char *str, int index = 0)
{
std::set<char> used;
char *p = str + index;
char *q = p;
if (*p == '\0') {
std::cout << str << std::endl;
return;
}
while (*q) {
if (used.find(*q) == used.end()) {
std::swap(*p, *q);
perm(str, index + 1);
std::swap(*p, *q);
used.insert(*q);
}
q++;
}
}
int main()
{
char arr[] = "AAABB";
perm(arr);
return 0;
}
This will produce 5! == 120 permutations for "ABCDE", but only 5! / (2! 3!) == 10 unique permutations for "AAABB". It will also create the 1260 permutations from the linked exercise.
What is the best way to store the state of a C++11 random generator without using the iostream interface. I would like to do like the first alternative listed here[1]? However, this approach requires that the object contains the PRNG state and only the PRNG state. In partucular, it fails if the implementation uses the pimpl pattern(at least this is likely to crash the application when reloading the state instead of loading it with bad data), or there are more state variables associated with the PRNG object that does not have to do with the generated sequence.
The size of the object is implementation defined:
g++ (tdm64-1) 4.7.1 gives sizeof(std::mt19937)==2504 but
Ideone http://ideone.com/41vY5j gives 2500
I am missing member functions like
size_t state_size();
const size_t* get_state() const;
void set_state(size_t n_elems,const size_t* state_new);
(1) shall return the size of the random generator state array
(2) shall return a pointer to the state array. The pointer is managed by the PRNG.
(3) shall copy the buffer std::min(n_elems,state_size()) from the buffer pointed to by state_new
This kind of interface allows more flexible state manipulation. Or are there any PRNG:s whose state cannot be represented as an array of unsigned integers?
[1]Faster alternative than using streams to save boost random generator state
I've written a simple (-ish) test for the approach I mentioned in the comments of the OP. It's obviously not battle-tested, but the idea is represented - you should be able to take it from here.
Since the amount of bytes read is so much smaller than if one were to serialize the entire engine, the performance of the two approaches might actually be comparable. Testing this hypothesis, as well as further optimization, are left as an exercise for the reader.
#include <iostream>
#include <random>
#include <chrono>
#include <cstdint>
#include <fstream>
using namespace std;
struct rng_wrap
{
// it would also be advisable to somehow
// store what kind of RNG this is,
// so we don't deserialize an mt19937
// as a linear congruential or something,
// but this example only covers mt19937
uint64_t seed;
uint64_t invoke_count;
mt19937 rng;
typedef mt19937::result_type result_type;
rng_wrap(uint64_t _seed) :
seed(_seed),
invoke_count(0),
rng(_seed)
{}
rng_wrap(istream& in) {
in.read(reinterpret_cast<char*>(&seed), sizeof(seed));
in.read(reinterpret_cast<char*>(&invoke_count), sizeof(invoke_count));
rng = mt19937(seed);
rng.discard(invoke_count);
}
void discard(unsigned long long z) {
rng.discard(z);
invoke_count += z;
}
result_type operator()() {
++invoke_count;
return rng();
}
static constexpr result_type min() {
return mt19937::min();
}
static constexpr result_type max() {
return mt19937::max();
}
};
ostream& operator<<(ostream& out, rng_wrap& wrap)
{
out.write(reinterpret_cast<char*>(&(wrap.seed)), sizeof(wrap.seed));
out.write(reinterpret_cast<char*>(&(wrap.invoke_count)), sizeof(wrap.invoke_count));
return out;
}
istream& operator>>(istream& in, rng_wrap& wrap)
{
wrap = rng_wrap(in);
return in;
}
void test(rng_wrap& rngw, int count, bool quiet=false)
{
uniform_int_distribution<int> integers(0, 9);
uniform_real_distribution<double> doubles(0, 1);
normal_distribution<double> stdnorm(0, 1);
if (quiet) {
for (int i = 0; i < count; ++i)
integers(rngw);
for (int i = 0; i < count; ++i)
doubles(rngw);
for (int i = 0; i < count; ++i)
stdnorm(rngw);
} else {
cout << "Integers:\n";
for (int i = 0; i < count; ++i)
cout << integers(rngw) << " ";
cout << "\n\nDoubles:\n";
for (int i = 0; i < count; ++i)
cout << doubles(rngw) << " ";
cout << "\n\nNormal variates:\n";
for (int i = 0; i < count; ++i)
cout << stdnorm(rngw) << " ";
cout << "\n\n\n";
}
}
int main(int argc, char** argv)
{
rng_wrap rngw(123456790ull);
test(rngw, 10, true); // this is just so we don't start with a "fresh" rng
uint64_t seed1 = rngw.seed;
uint64_t invoke_count1 = rngw.invoke_count;
ofstream outfile("rng", ios::binary);
outfile << rngw;
outfile.close();
cout << "Test 1:\n";
test(rngw, 10); // test 1
ifstream infile("rng", ios::binary);
infile >> rngw;
infile.close();
cout << "Test 2:\n";
test(rngw, 10); // test 2 - should be identical to 1
return 0;
}
The following is a code for sorting numbers based on quicksort in C. To optimize for speed, scanf() has been replaced by fread(). But on printing the sorted list, all garbage values come out. The exact problem statement is on :http://www.codechef.com/problems/TSORT
#define SIZE 32768
#include <stdio.h>
#include <stdlib.h>
int compare(const void *a, const void *b)
{
return (*(unsigned long *)a-*(unsigned long *)b);
}
int main()
{
char buffer[SIZE];
register int readBytes=0;
unsigned long bufferCounter=0, bufferedInput=0;
unsigned long * array, t, i;
scanf("%lu", &t); fflush(stdin);
array=(unsigned long *) malloc(sizeof(long)*t);
i=-1;
while(readBytes=fread(buffer, sizeof(char), SIZE, stdin)>0)
{
for(bufferCounter=0; bufferCounter<readBytes; bufferCounter++)
{
if(buffer[bufferCounter]=='\n' || buffer[bufferCounter]==' ')
{
array[++i]=bufferedInput;
bufferedInput=0;
}
else bufferedInput=bufferedInput*10+(buffer[bufferCounter]-'0');
}
}
qsort(array, t, sizeof(long), compare);
for(i=0; i<t; i++)
{
printf("%lu\n", array[i]);
}
return 0;
}
The code is compiled in Codeblocks and the input is piped from a file.
The input file is :
5
5
3
6
7
1
The output obtained is:
5050160
5056368
1465662019
1868852841
1935438711
What is the problem with my code?