how to count the characters in a text file - c++

im trying to count the characters inside a text file in c++, this is what i have so far, for some reason im getting 4. even thou i have 123456 characters in it. if i increase or decrease the characters i still get 4, please help and thanks in advance
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const char FileName[] = "text.txt";
int main ()
{
string line;
ifstream inMyStream (FileName);
int c;
if (inMyStream.is_open())
{
while( getline (inMyStream, line)){
cout<<line<<endl;
c++;
}
}
inMyStream.close();
system("pause");
return 0;
}

You're counting the lines.
You should count the characters. change it to:
while( getline ( inMyStream, line ) )
{
cout << line << endl;
c += line.length();
}

There are probably hundreds of ways to do that.
I believe the most efficient is:
inMyStream.seekg(0,std::ios_base::end);
std::ios_base::streampos end_pos = inMyStream.tellg();
return end_pos;

First of all, you have to init a local var, this means:
int c = 0;
instead of
int c;
I think the old and easy to understand way is to use the get() function till the end char EOF
char current_char;
if (inMyStream.is_open())
{
while(inMyStream.get(current_char)){
if(current_char == EOF)
{
break;
}
c++;
}
}
Then c will be the count of the characters

this is how i would approach the problem:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main ()
{
string line;
int sum=0;
ifstream inData ;
inData.open("countletters.txt");
while(!inData.eof())
{
getline(inData,line);
int numofChars= line.length();
for (unsigned int n = 0; n<line.length();n++)
{
if (line.at(n) == ' ')
{
numofChars--;
}
}
sum=numofChars+sum;
}
cout << "Number of characters: "<< sum << endl;
return 0 ;
}

Just use good old C FILE pointers:
int fileLen(std::string fileName)
{
FILE *f = fopen(fileName.c_str(), "rb");
if (f == NULL || ferror(f))
{
if (f)
fclose(f);
return -1;
}
fseek(f, 0, SEEK_END);
int len = fell(f);
fclose(f);
return len;
}

I found out this simple method , hope this helps
while(1)
{
if(txtFile.peek() == -1)
break;
c = txtFile.get();
if(c != txtFile.eof())
noOfChars++;
}

This works for sure, it is designed to read character by character.
It could be easily put into a class and you may apply function for every char, so you may check for '\n', ' ' and so on. Just have some members in your class, where they can be saved, so you may only return 0 and use methods to get what exactly you want.
#include <iostream>
#include <fstream>
#include <string>
unsigned long int count(std::string string)
{
char c;
unsigned long int cc = 0;
std::ifstream FILE;
FILE.open(string);
if (!FILE.fail())
{
while (1)
{
FILE.get(c);
if (FILE.eof()) break;
cc++; //or apply a function to work with this char..eg: analyze(c);
}
FILE.close();
}
else
{
std::cout << "Counter: Failed to open file: " << string << std::endl;
}
return cc;
};
int main()
{
std::cout << count("C:/test/ovecky.txt") << std::endl;
for (;;);
return 0;
}

C++ provides you with a simple set of functions you can use to retrieve the size of stream segment.
In your case, we want to find the file end, which can be done by using fstream::seekg, and providing the fstream::end.
note that fstream is not implementing the end iterator overload, this is it's own end constant
When we've seeked towards the end of the file, we want to get the position of the stream pointer, using tellg (also known as the character count in our case).
But we're not done yet. We need to also set the stream pointer to its original position, otherwise we'll be reading from the end of the file. Something we don't want to do.
So lets call fstream::seekg again, but this time set the position to the begining of the file using fstream::beg
std::ifstream stream(filepath);
//Seek to end of opened file
stream.seekg(0, stream.end);
int size = stream.tellg();
//reset file pointer to the beginning of the file
stream.seekg(0, stream.beg);

Related

arrange line in txt file in ASCII order using array and display them

#include <stdio.h>
#include <string.h>
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ifstream infile; // ifstream is reading file
infile.open("read.txt"); // read.txt is the file we need to read
std::cout << infile;
string str;
if (infile.is_open()) {
while (getline(infile, str)) {
char str[2000], ch;
int i, j, len;
len = strlen(str);
for (i = 0; i < len; i++) {
for (j = 0; j < (len - 1); j++) {
if (str[j] > str[j + 1]) {
ch = str[j];
str[j] = str[j + 1];
str[j + 1] = ch;
}
}
}
}
cout << "\nProcessed data:" << str;
}
return 0;
}
My txt file:
Today is a fine day.
It’s sunny.
Let us go out now!
My result should be:
.Taaaddefiinosyy
’.Innsstuy
!Legnooosttuuw
Spaces is consider here as well.
I'm new to C++.
I need some pros help.
Thank you very much!
Making use of the STL:
Read your file line by line into a std::string using std::getline.
Sort every line using std::ranges::sort.
Print it.
The example below:
also uses the fmt library instead of std::cout, and
reads from a std::istringstream instead of a std::ifstream.
[Demo]
#include <algorithm> // sort
#include <fmt/core.h>
#include <sstream> // istringstream
#include <string> // getline
int main() {
std::istringstream iss{
"Today is a fine day.\n"
"It's sunny.\n"
"Let us go out now!\n"
};
fmt::print("Original file:\n{}\n", iss.str());
fmt::print("Processed file:\n");
std::string line{};
while (std::getline(iss, line)) {
std::ranges::sort(line);
fmt::print("{}\n", line);
}
}
// Outputs:
//
// Original file:
// Today is a fine day.
// It's sunny.
// Let us go out now!
//
// Processed file:
// .Taaaddefiinosyy
// '.Innsstuy
// !Legnooosttuuw
Your code does not work, because:
The line std::cout << infile; is wrong. If you want to print the result of istream::operator bool() in order to determine whether the file was successfully opened, then you should write std::cout << infile.operator bool(); or std::cout << static_cast<bool>(infile); instead. However, it would probably be better to simply write std::cout << infile.fail(); or std::cout << !infile.fail();.
The function std::strlen requires as a parameter a pointer to a valid string. Maybe you intended to write str.length()? In that case, you should delete the declaration char str[2000], because it shadows the declaration string str;.
You should print the sorted result immediately after sorting it, before it gets overwritten by the next line. Currently you are only printing the content str a single time at the end of your program, so you are only printing the last line.
After performing the fixes mentioned above, your code should look like this:
#include <stdio.h>
#include <string.h>
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ifstream infile; // ifstream is reading file
infile.open("read.txt"); // read.txt is the file we need to read
std::cout << infile.fail();
string str;
if (infile.is_open()) {
while (getline(infile, str)) {
char ch;
int i, j, len;
len = str.length();
for (i = 0; i < len; i++) {
for (j = 0; j < (len - 1); j++) {
if (str[j] > str[j + 1]) {
ch = str[j];
str[j] = str[j + 1];
str[j + 1] = ch;
}
}
}
cout << "\nProcessed data:" << str;
}
}
return 0;
}
For the input
Today is a fine day.
It's sunny.
Let us go out now!
this program has the following output:
0
Processed data: .Taaaddefiinosyy
Processed data: '.Innsstuy
Processed data: !Legnooosttuuw
Note that the input posted in your question contains a forward tick ’ instead of an apostrophe '. This could cause trouble. For example, when I tested your program, this forward tick was encoded into a multi-byte UTF-8 character, because it is not representable in 7-bit US-ASCII. This caused your sorting algorithm to fail, because it only supports single-byte characters. I was only able to fix this bug by replacing the forward tick with an apostrophe in the input.

Having an issue passing an array to a Function as only first word is printed c++

I am new to passing values to functions, please guide me what I am doing wrong here, thanks!
The question: Write a C++ program in which, read a c-string sentence
one by one from a file “sentence .txt”. Now your task is to break each
word of sentence into another c-string word, now write that word into
a file “word.txt”. Note : You must create atleast 1 function to
separate the words from sentence, you cannot use strings.
#include <iostream>
#include <fstream>
using namespace std;
char sentence2word(char array[100])
{
ofstream fout2;
fout2.open("word.txt");
fout2 << array << endl;
return array[100];
}
int main()
{
ifstream fin;
fin.open("sentence.txt");
char array[100];
fin >> array;
cout << "Output successful!";
sentence2word(array);
return 0;
system("pause");
}
The following program show how to get started with reading and writing from/into text files in C++. This is just to get you started and in practice i use std::string and std::istringstream to do this but in your note it is written that we cannot use strings so i did not use std::string. The program reads line by line from an input.txt file and write word by word into an output.txt file.
#include <iostream>
#include <fstream>//needed to read/write files
#define MAX_NUMBER_OF_CHARACTERS 500
using namespace std;
//function that writes lines word by word into output.txt
void writeWordByWord(std::ofstream &m_outFile, char (&lineArg)[MAX_NUMBER_OF_CHARACTERS])
{ int i = 0;
while(lineArg[i] != '\0')
{
if(lineArg[i] != ' ')
{m_outFile << lineArg[i];
//std::cout<< lineArg[i]<<" wrote"<<std::endl;
++i;
}
else{
m_outFile << '\n';
++i;
}
}
//m_outFile << '\n';
}
int main()
{
cout << "Hello World" << endl;
char line[MAX_NUMBER_OF_CHARACTERS];
std::ifstream inFile("input.txt");
std::ofstream outFile("output.txt");
while(inFile.getline(line, MAX_NUMBER_OF_CHARACTERS, '\n'))
{
std::cout<<line<<std::endl;
writeWordByWord(outFile, line);
}
inFile.close();
outFile.close();
return 0;
}

C++ function `getline()` doesn't work correctly for char[]

I need to extract the first 150 characters from a line and save them in a char[] array (no strings allowed). My code below doesn't work and i just can't find the reason why:
#include <ifstream>
#include <iostream>
using namespace std;
int main()
{
ifstream myFile;
myFile.open("message.txt");
if(!myFile.is_open()) cout<<"error"; //added this after edit
const int SIZE = 151;
char buffer[SIZE]={};
while(myFile.getline(buffer, 151)){
buffer[150]='\0';
cout<<buffer<<endl;
}
myFile.close();
}
Here's a snippet of "message.txt":
abcdefg
hijklmn
opqrstuv
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
hello
It simply prints out nothing. The file "message.txt" exists and has several lines of characters in it. Where am I wrong?
EDIT: if the characters on a line are less than 150, they should all be read. If they are more than 150, the rest should be ignored.
If you are trying to read the first 150 characters of the 1st line, then you don't need the while loop. And you don't need to null-terminate the buffer manually, istream::getline() will do that for you, eg:
#include <ifstream>
#include <iostream>
using namespace std;
int main()
{
ifstream myFile("message.txt");
if (!myFile.is_open())
{
cout << "error";
return 0;
}
const int SIZE = 151;
char buffer[SIZE] = {};
myFile.getline(buffer, SIZE);
cout << buffer << endl;
myFile.close();
return 0;
}
If you want to read the first 150 characters of a specific line only, then you need a loop to skip all lines regardless of their length until you reach the desired line, and then you can read the 150 characters of just that line, eg:
#include <ifstream>
#include <iostream>
#include <limits>
using namespace std;
int main()
{
ifstream myFile("message.txt");
if (!myFile.is_open())
{
cout << "error";
return 0;
}
size_t lineIndex = ...;
while (lineIndex > 0)
{
if (!myFile.ignore(numeric_limits<streamsize>::max(), '\n'))
{
cout << "error";
return 0;
}
if (myFile.eof())
{
cout << "eof";
return 0;
}
--lineIndex;
}
const int SIZE = 151;
char buffer[SIZE] = {};
myFile.getline(buffer, SIZE);
cout << buffer << endl;
myFile.close();
return 0;
}
If you want to read the first 150 characters of each line, then after a successful read you need to skip any remaining characters prior to a line break before you can then read the next line, eg:
#include <ifstream>
#include <iostream>
#include <limits>
using namespace std;
int main()
{
ifstream myFile("message.txt");
if (!myFile.is_open())
{
cout << "error";
return 0;
}
const int SIZE = 151;
char buffer[SIZE] = {};
do
{
myFile.getline(buffer, SIZE);
if (myFile.bad())
{
cout << "error";
return 0;
}
if (myFile.fail())
{
// SIZE-1 characters were extracted before a line break
// was reached, need to reset the error to keep going...
myFile.clear();
myFile.ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << buffer << endl;
}
while (!myFile.eof());
myFile.close();
return 0;
}

unique words from a file c++

ts been 3 days i just cant identify whats wrong with the program the program should compare words by words instead it only comparing a character to charcter its is showing like if i have words like (aaa bbb cc dd ) the result its printing is a b and same is the sentence file if i put paragraphs to compare its only comparing few character please help me
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream myfile("unique.text");
int count = 0;
string temp;
string a;
int i,j;
while(getline(myfile,temp))
{
for(i=0 ; i < sizeof(temp); i++)
{
for(int j = 0; j < i; j++)
{
if (temp[i] == temp[j])
break;
}
if (i == j)
cout << temp [i] <<" , ";
}
myfile.close ();
}
You have a couple of problems
temp is of type string. sizeof is not the way to determine the length of a string (it's used for determining things like the number of bytes in an int). You want:
temp.length()
Secondly, indexing into a string (temp[n]) gives you the nth character, not the nth word.
You can make getline split into words by adding a third delimiter parameter:
getline (myfile, temp, ' '))
So, some bugs in your code.
Mixing up characters and strings, closing the file in the while loop and not storing last words.
One recommenadtion. Before you write code, write comments for what you want to do.
Meaning, make a design, before you start coding. That is very important.
For your problem at hand in the title of this thread:
unique words from a file c++
I prepared 3 different solutions. The first is just using very simple constructs. The second is using a std::vector. And, the 3rd is the C++ solution using the C++ algorithm library.
Please see:
Simple, but lengthy
And not recommended, because we should not use raw pointers for owned memory and should not use new
#include <iostream>
#include <fstream>
#include <string>
const std::string fileName{ "unique.text" };
unsigned int numberOfWords() {
// Here we will count the number of words in the file
unsigned int counter = 0;
// Open the file. File must not be already open
std::ifstream sourceFileStream(fileName);
// Check, if we could open the file
if (sourceFileStream) {
// Simply read all words and increment the counter
std::string temp;
while (sourceFileStream >> temp) ++counter;
}
else {
// In case of problem
std::cerr << "\nCould not open file '" << fileName << "'\n";
}
return counter;
}
int main() {
// Get the number of words in the source file
unsigned size = numberOfWords();
// Allocate a dynamic array of strings. Size is the count of the words in the file
// Including doubles. So we will waste a little bit of space
std::string* words = new std::string[size+1];
// Open the source file
std::ifstream sourceFileStream(fileName);
// Check, if it could be opened
if (sourceFileStream) {
// We will read first into a temporary variable
std::string temp;
// Her we will count number of the unique words
unsigned int wordCounter = 0;
// Read all words in the file
while (sourceFileStream >> temp) {
// We will search, if we have read alread the word before. We assume NO for the beginning
bool wordIsAlreadyPresent = false;
// Go through all alread read words, and check, if the just read word is already existing
for (unsigned int i = 0; i < wordCounter; ++i) {
// Check, if just read word is already in the word array
if (temp == words[i]) {
// Yes it is, set flag, and stop the loop.
wordIsAlreadyPresent = true;
break;
}
}
// if the word was not already there
if (! wordIsAlreadyPresent) {
// Then add the just read temporary word into our array
words[wordCounter] = temp;
// And increment the counter
++wordCounter;
}
}
// Show all read unique words
for (unsigned int i = 0; i < wordCounter; ++i) {
std::cout << words[i] << "\n";
}
}
else { // In case of error
std::cerr << "\nCould not open file '" << fileName << "'\n";
}
delete[] words;
}
Using a vector. Already more compact and better readable
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
const std::string fileName{ "unique.text" };
int main() {
// Open the source file
std::ifstream sourceFileStream(fileName);
// Check, if the source file is oepen
if (sourceFileStream) {
// Temporary string for holding just read words
std::string temp;
// In this vector we will store all unique words
std::vector<std::string> words;
// Read all words from the source file
while (sourceFileStream >> temp) {
// We will search, if we have read alread the word before. We assume NO for the beginning
bool wordIsAlreadyPresent = false;
// Go through all alread read words, and check, if the just read word is already existing
for (unsigned int i = 0; i < words.size(); ++i) {
// Check, if just read word is already in the word vector
if (temp == words[i]) {
// Yes it is, set flag, and stop the loop.
wordIsAlreadyPresent = true;
break;
}
}
// if the word was not already there
if (not wordIsAlreadyPresent) {
// Then add the just read temporary word into our array
words.push_back(temp);
}
}
for (unsigned int i = 0; i < words.size(); ++i) {
std::cout << words[i] << "\n";
}
}
else {
std::cerr << "\nCould not open file '" << fileName << "'\n";
}
}
And 3., more advance C++ programming. Just very few lines and elegant code.
But too difficult to understand for starters.
#include <iostream>
#include <fstream>
#include <set>
#include <string>
#include <iterator>
#include <algorithm>
const std::string fileName{ "unique.text" };
int main() {
// Open the source file and check, if it could be opend and there is no failure
if (std::ifstream sourceFileStream(fileName); sourceFileStream) {
// Read all words (everything delimited by a white space) into a set
std::set words(std::istream_iterator<std::string>(sourceFileStream), {});
// Now we have a set with all unique words. Show this on the screen
std::copy(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
}
// If we could not open the source file
else {
std::cerr << "\nCould not open file '" << fileName << "'\n";
}
return 0;
}

Reading in a text file from a command line and storing the content of the file into a c-string

I am learning C++ in one of my classes and I am having difficulties storing the content of a .txt file into a c string.
I have figured out how to validate that the .txt file exists but when I try storing the characters into a c-string it crashes.
This is my most recent attempt:
char * fileContent[MAX_SIZE];
ifstream ifile(argv[1]);
while (int i = 0 < MAX_SIZE)
{
ifile >> fileContent[i];
cout << fileContent[i];
if (ifile.eof())
break;
i++;
}
ifile.close();
Every-time the console gets to the loop it crashes. Are there any suggestions to help make this work?
I need it to be a c-string so that I can run the c-string through other functions. I am still pretty new to C++.
The assignment states: "Reads a text file into memory, one byte at a time"
I hope what I am trying to do is this.
Thank you
You can use the following code to read from a text file and save the string as a C-string. The output file (output.txt) contains the c-string output.
#include <string>
#include <iostream>
#include <fstream>
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
char *out_c_string;
char ch;
int index=0;
while(cin >> ch)
out_c_string[index++] = ch;
for(int i=0; i<index; i++)
cout << out_c_string[i]; // the c string of the file :)
return 0;
}
There were few bugs in your code, try this:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int MAX_SIZE = 128;
int main(int argc, char* argv[])
{
char fileContent[MAX_SIZE]; //bad idea never do that!
// use an std::vector<char> instead!
// and reverse a minimum amount of chars
// using `reserve` if you are after performance
ifstream ifile(argv[1]);
int i = 0;
while (i < MAX_SIZE)
{
ifile >> fileContent[i];
cout << fileContent[i];
if (ifile.eof())
break;
i++;
}
ifile.close();
}
Combining everyones answers, I got this as my function:
void get_file_info(char * argv, char (&fileContent) [MAX_SIZE], int & filesize ){
freopen(argv, "r", stdin);
char ch;
int index = 0;
while (cin >> noskipws >> ch)
fileContent[index++] = ch;
cout << endl << index << endl;
#if SHOW_DEBUG_CODE
for (int count = 0; count < index; count++)
cout << fileContent[count];
#endif
fclose(stdin);
}
It seems to work just fine. I will look into vectors my next free time but for right now, I am going to continue with char array.
Thank you for your suggestions.
I would do this. It's more general to cope with any size file.
void ReadFile(char*file,char**buff,int*size){
// Open file as binary putting file position at the end
ifstream is(file,ios::binary|ios::ate);
// Get the current file position, which is the file end
*size=is.tellg();
// Put file pointer back at the start
is.seekg(0,ios::beg);
// errors
if (!*size){
cout<<"Unable to open input file or file empty\n";
exit(9);
}
// allocate a buffer one bigger to allow for zero terminator
*buff=new char[*size+1];
// read the whole file in one hit
is.read(*buff,*size);
// Done. So close and zero delimit data.
is.close();
*(*buff+*size)=0;
}