I have the following program:
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
void tellen ()
{
ifstream input;
ofstream output;
char kar;
input.open ("test",ios::in);
kar = input.get();
while ( !input.eof() ){
if ( kar >= '0' and kar <= '9'){
cout << kar;
kar = input.get();
}
else
kar = input.get();
}
//cout << "Aantal characters:" << aantalchar << endl;
//cout << "Aantal regels:" << aantalregels << endl;
}
int main()
{
tellen();
return 0;
} //main
What I intended this program to do is to show me all numbers in a certain text file ("Test" in this case) in the command window. I'm wondering why this doesn't work? I have a file called test but when I run this the command prompt gives me a blank. The problem persists when I change "test" to "test.txt". Does anyone have a clue what the problem is? Maybe it has to do with the location of the file?
The following code will give you output of a txt file called test.
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
void tellen() {
ifstream input;
ofstream output;
int kar;
char charKar;
input.open("test.txt", ios::in);
// could replace "test.txt" with a variable such as filePath = "/downloads/test.txt"
if (input.is_open()) {
while (!input.eof()) {
kar = input.get(); //kar gets inputed as an ASCII
charKar = static_cast<char>(kar);//charKar converts the ASCII into a char variable
if (charKar >= '0' && charKar <= '9'){ //Evaluate charKar, not kar
cout << charKar << endl;
}
}
input.close();
}
else {
cout << "\nFile Did Not Open!";
}
}
int main() {
tellen();
return 0;
} //main
I have tested the code and it works! Sorry if it's messy I was making eggs while coding this so if you have any questions just ask!
Things to change:
Add a check to make sure that the file was opened successfully.
Use type int when reading characters using istream::get() instead of char.
Change the while statement a bit.
void tellen (){
ifstream input;
ofstream output;
input.open ("test",ios::in);
if ( !input )
{
std::cerr << "Unable to open file.\n";
return;
}
int kar; // Don't use char.
while ( (kar = input.get()) != EOF ){
if ( kar >= '0' and kar <= '9'){
cout.put(kar); // I prefer this.
// cout << (char)kar;
}
}
//cout << "Aantal characters:" << aantalchar << endl;
//cout << "Aantal regels:" << aantalregels << endl;
}
Related
I am supposed to ask the user for two file names (input and output files). The contents from the input file should be read and the first letter of each sentence should be made uppercase while every other letter should be made lowercase. The results should then be stored in the output file.
I am aware that there are ways of using the toupper and tolower functions that include pointers, arrays, or even ASCII values of chars but I am trying to get this code to work by using if/else and while statements, as well as boolean statements. I have had various results ranging from all the letters being capitalized to none of the letters being capitalized however, I think right now I am on the right track with the code and am just overlooking the way I am incrementing through the characters causing the code to not capitalize after a period and a space.
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
int main() {
string input_file; // To hold input file name
string output_File; // To hold output file name
char ch; // To hold character
fstream inputFile;
fstream outputFile;
bool new_sentence = true;
cout << "Enter input file name: " << endl;
cin >> input_file;
cout << "Enter output file name: " << endl;
cin >> output_File;
outputFile.open(output_File, ios::out);
inputFile.open(input_file, ios::in);
if (inputFile) {
while (inputFile.get(ch)) {
if (isprint(ch)) {
if (new_sentence) {
outputFile.put(toupper(ch));
}
else {
outputFile.put(tolower(ch));
}
new_sentence = false;
}
else {
if (ch == '.') {
new_sentence = true;
outputFile.put(ch);
}
}
}
inputFile.close();
outputFile.close();
}
else {
cout << "Cannot open file(s)." << endl;
}
cout << "\nFile conversion complete." << endl;
return 0;
}
With my current code I am able to capitalize the first letter of the first sentence and make every other letter lowercase. I am able to store and show the results in the output file. My issue is that the first letter of every other sentence after the first one won't change to uppercase. This makes me think the issue is in this part of the code:
if (new_sentence)
{
outputFile.put(toupper(ch));
}
else
{
outputFile.put(tolower(ch));
}
Am I missing something here?
You have a minor logical error.
You first need to check, if the character is a period. This state you need to remember. If then a next character isalpha, then we check, if recently the newsentence flag has been set. In this case, and only in this case, we reset the new sentence flag and convert the character to uppercase.
All other alpha characters will be converted to lowercase. Other charcaters will not be converted.
In your solution you always reset the newsentence flag. Even, if the next print character is a space (Which is most liekly the case).
Please see updated solution:
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
int main() {
string input_file; // To hold input file name
string output_File; // To hold output file name
char ch; // To hold character
fstream inputFile;
fstream outputFile;
bool new_sentence = true;
cout << "Enter input file name: " << endl;
cin >> input_file;
cout << "Enter output file name: " << endl;
cin >> output_File;
outputFile.open(output_File, ios::out);
inputFile.open(input_file, ios::in);
if (inputFile) {
while (inputFile.get(ch)) {
if (ch == '.') {
new_sentence = true;
}
if (isalpha(ch)) {
if (new_sentence) {
ch = toupper(ch);
new_sentence = false;
}
else {
ch = tolower(ch);
}
}
outputFile.put(ch);
}
inputFile.close();
outputFile.close();
}
else {
cout << "Cannot open file(s)." << endl;
}
cout << "\nFile conversion complete." << endl;
return 0;
}
And then, please see some further improvements:
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
int main() {
// Will hold the input and output filename
std::string filename;
// This is our flag to indicate that a new sentence will come
bool newSentence = true;
// Get input filename
std::cout << "Enter input file name: " << "\n";
std::cin >> filename;
// And try to open the file
std::ifstream inFile(filename);
std::cout << "Enter output file name: " << "\n";
std::cin >> filename;
// And try to open the file
std::ofstream outFile(filename);
// Only convert, if the input and output file could be opened
if (inFile && outFile) {
char ch;
while (inFile.get(ch)) {
if (ch == '.') {
newSentence = true;
}
if (isalpha(ch)) {
if (newSentence) {
ch = toupper(ch);
newSentence = false;
}
else {
ch = tolower(ch);
}
}
outFile.put(ch);
}
}
else {
std::cout << "Cannot open file(s)\n";
}
std::cout << "\nFile conversion program complete\n";
return 0;
}
And the full blown "C++ with algorithm" solution. Here the conversion, or transformation is done in one statement
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
#include <algorithm>
#include <iterator>
int main() {
// Will hold the input and output filename
std::string filename;
// Get input filename
std::cout << "Enter input file name: " << "\n";
std::cin >> filename;
// And try to open the file
std::ifstream inFile(filename);
std::cout << "Enter output file name: " << "\n";
std::cin >> filename;
// And try to open the file
std::ofstream outFile(filename);
// Only convert, if the input and output file could be opened
if (inFile && outFile) {
// Do the conversion
std::transform(
std::istreambuf_iterator<char>(inFile),
std::istreambuf_iterator<char>(),
std::ostreambuf_iterator<char>(outFile),
[newSentence = true](char c) mutable {
if (c == '.') newSentence = true;
if (std::isalpha(c))
if (newSentence) {
newSentence = false;
c = std::toupper(c); }
else c = std::tolower(c);
return c;
}
);
}
else {
std::cout << "Cannot open file(s)\n";
}
std::cout << "\nFile conversion program complete\n";
return 0;
}
But if the last solution adds additional value? I am not sure . . .
This part of your code should be changed:
// if (isprint(ch)) {
if (ch != '.') {
if (new_sentence) {
outputFile.put(toupper(ch));
}
else {
outputFile.put(tolower(ch));
}
new_sentence = false;
}
else {
new_sentence = true;
outputFile.put(ch);
}
std::isprint() only checks if the character is printable.
Full code:
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
int main() {
string input_file; // To hold input file name
string output_File; // To hold output file name
char ch; // To hold character
fstream inputFile;
fstream outputFile;
bool new_sentence = true;
cout << "Enter input file name: " << endl;
cin >> input_file;
cout << "Enter output file name: " << endl;
cin >> output_File;
outputFile.open(output_File, ios::out);
inputFile.open(input_file, ios::in);
if (inputFile) {
while (inputFile.get(ch)) {
if (ch != '.') {
if (new_sentence) {
outputFile.put(toupper(ch));
}
else {
outputFile.put(tolower(ch));
}
new_sentence = false;
}
else {
new_sentence = true;
outputFile.put(ch);
}
}
inputFile.close();
outputFile.close();
}
else {
cout << "Cannot open file(s)." << endl;
}
cout << "\nFile conversion complete." << endl;
return 0;
}
I use getchar() and loop to get a text and use fputc() to put into the text file, but it always leaves the first line empty in the text file after writing. The loop stops when character input is a dot (.). How can I delete the first line?
Updated (12/29/2016): I used DevC++ and the codes run finely without creating an empty blank, but my VisualStudio2015 had the problem.
Example: create a file named test.txt
input: this is a text.
output: (in the text file)
[ a blank line ]
this is a text
void writeFile(char *fileName){
FILE *fp;
fp = fopen(fileName, "wt"); //write text
if (fp == NULL) {
cout << "Failed to open" << endl;
fclose(fp);
}
else {
int i = 0;
char c = '\0';
cout << "Enter a text and end with dot (.): ";
fflush(stdin);
//c = getchar();
while (c != '.') {
fputc(c, fp);
c = getchar();
}
cout << "Written successfully" << endl;
fclose(fp);
}
}
Out of curiosity, is there a reason for the C functions? Doing something like this in C++ would be better suited to using streams, like:
#include <iostream>
#include <fstream>
using namespace std;
void writeFile(const char *fileName)
{
ofstream writeToFile;
writeToFile.open(fileName);
if (!writeToFile.is_open()) {
cout << "Failed to open" << endl;
return;
} else {
string stringToWrite{""};
char c = '\0';
cout << "Enter a text and end with dot (.): ";
while (c != '.') {
std::cin >> c;
stringToWrite += c;
}
writeToFile << stringToWrite << endl;
cout << "Written successfully" << endl;
writeToFile.close();
}
}
int main()
{
const char *fileName="test.txt";
writeFile(fileName);
return 0;
}
or, alternatively:
#include <iostream>
#include <fstream>
using namespace std;
void writeFile(const char *fileName)
{
ofstream writeToFile;
writeToFile.open(fileName);
if (!writeToFile.is_open()) {
cout << "Failed to open" << endl;
return;
} else {
string stringToWrite{""};
cout << "Enter text and press return: ";
getline(cin, stringToWrite);
writeToFile << stringToWrite << endl;
cout << "Written successfully" << endl;
writeToFile.close();
}
}
int main()
{
const char *fileName="test.txt";
writeFile(fileName);
return 0;
}
c is 0 on the first pass, hence the blank line.
change the while loop to
while( (c = getchar()) != EOF)
{
if(c == '.')
break;
}
It looks a bit odd, but is idiomatic for reading characters from a stream in C.
I am currently trying to build a program that reads in a file, scans through that file, and outputs all words in that file surrounded by " marks. I am currently stumped and was hoping to get some help!
#include <iostream>
// For file I/O:
#include <fstream>
#include <cstdlib>
#include <iomanip>
using namespace std;
// Prototype the count function so we can have it below it's first
// use in main().
void count(istream& in, int& lines, int& words, int& characters);
/*
* wc <filename>
*/
int main(int argc, char *argv[])
{
if (argc < 2) {
cerr << "Usage: wc <filename>" << endl;
return 0;
}
// Open the file specified by argv[1] for reading:
// Constructs a ifstream object called "in":
ifstream in(argv[1]);
// Was there a problem opening the file?
if (!in.good()) {
cerr << "Unable to open file [" << argv[1] << "] for reading." << endl;
return 1;
}
int lines = 0, words = 0, characters = 0;
count(in, lines, words, characters);
cout << setw(5) << lines << " " << words << " " <<
characters << " " << argv[1] << endl;
// Close the input stream:
in.close();
}
void count(istream& in, int& lines, int& words, int& characters)
{
int i;
char s;
int ch;
bool inword = false;
// Read until the end of file is reached, or there was an error:
while (!in.eof()) {
// Read a character from the input stream "in":
s = in.get(); //Set char s = in.get
for(i=0; s != 0; i++){ //Loop to iterate through the characters
while(s == '"'){ //While s is equal "
cout << s << endl; // Print s
if(s == '"') // If we hit another ", then we break
break;
}
}
if (in.good() == false) return;
characters++;
if (!isspace(ch) && !inword) {
inword = true;
words++;
} else if (isspace(ch) && inword) {
inword = false;
}
if (ch == '\n') lines++;
}
}
your algorithm seems wrong.. in the for loop you compare to 's' but you're not updating it... try something like this in your main loop(QnD):
while (!in.eof() && (s = in.get()) != '"'); // read to first quote char
/* this is the word we want.. run to end quote marks.. */
while (!in.eof() && (s = in.get()) != '"') {
cout << s;
}
cout << endl;
I am working on a project where I will be able to read in a file that contains any text, like the sample text below. Then, character by character, it will be able to output n-character long sequences (represented below as a read-in value given by the user along the lines of 1, 2, 3, 4...) along the whole length of the text. So, for example:
As Gregor Samsa awoke one morning from uneasy dreams he found himself transformed in his bed into a gigantic insect.
If the user provided 2 as the sequence length, the program should spit out: "As" "s " " G" "Gr" "re" "eg" "go" "or" "r " and so on...
I have written this code but don't know why it won't work. Right now, it doesn't spit out every possible variation of the sequence. Any suggestions would be very helpful. Thanks.
#include "genlib.h"
#include <iostream>
#include <fstream>
#include "simpio.h"
#include "random.h"
#include "vector.h"
#include "map.h"
/* Private Instance Variables */
int seed_length;
string line;
string seed_string;
string next_string;
char ch;
/* Function Prototypes */
string promptUserForFile(ifstream & infile);
int main() {
ifstream infile;
promptUserForFile(infile);
// Ask what order of Markov model to use.
cout << "What order of Markov model should we use? ";
cin >> seed_length;
while (infile.eof() == false) {
ch = infile.get();
for (int i = 0; i < seed_length - 1; i++) {
cout << "ch up here is " << ch << endl;
if (isspace(ch) && i == 0) {
seed_string += ch;
} else {
seed_string += ch;
ch = infile.get();
}
}
next_string = ch;
if (isspace(ch)) {
next_string = " ";
} else {
char trythis = infile.get();
next_string += trythis;
}
cout << seed_string << endl;
cout << next_string << endl;
seed_string = "";
next_string = "";
}
cout << "TEST" << endl;
// Close the file when you're done storing all of the scores.
infile.close();
return 0;
}
string promptUserForFile(ifstream & infile) {
string prompt = "Please input your filename: ";
while(true) {
cout << prompt;
string filename;
getline (cin, filename);
infile.open(filename.c_str());
if(!infile.fail()) return filename;
infile.clear();
cout << "Unable to open that file. Try again." << endl;
if (prompt == "") prompt == "Input file: ";
}
return 0;
}
The code has two problems.
The special handling for isspace is broken:
if (isspace(ch) && i == 0) {
seed_string += ch;
} else {
seed_string += ch;
ch = infile.get();
}
This essentially means that if the first character in this loop is a space, it will be added twice.
Every character received from infile.get() is only added to seed_string once (with the exception of isspace characters).
A better way to code this is to recognize that:
You have to ignore consecutive isspace characters.
Every sequence can be obtained by removing the first character of the preceding sequnce and appending the next character from the file.
Here is a better implementation; it takes the order of the Markov model in the first command line parameter and takes the text from standard input. By encapsulating the skipping of duplicate spaces in a separate function, you don't have to deal with it in the main body of the algorithm.
#include <iostream>
#include <cstdlib>
char next_character() {
static bool was_space = false;
char ret = 0;
do {
ret = std::cin.get();
} while (was_space && std::isspace(ret));
if (std::isspace(ret)) {
was_space = true;
ret = ' ';
} else {
was_space = false;
}
return ret;
}
int main(int argc, char **argv) {
if (argc != 2) return 0;
int mlen = std::atoi(argv[1]);
std::string seq;
for (unsigned i = 0; i < mlen; ++i) {
seq += next_character();
}
std::cout << seq << '\n';
while (true) {
seq.erase(0, 1);
char c = next_character();
if (std::cin.eof()) break;
seq += c;
std::cout << seq << '\n';
}
return 0;
}
Example input:
This is a test
Example output:
This
his i
is is
s is
is a
is a
s a t
a te
a tes
test
I am trying to read a file with multiple columns to output all results with an income of over $100,000 and a GPA of less than or equal to 2.3. I'm not able to figure out which approach is correct. The file output does not even appear on the terminal. Please let me know if more specifics are needed. Here is the FILE.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream inputFile;
char *student = new char[];
int salary=100000,
grades=2.3;
inputFile.open("Students.txt");
if(inputFile.fail()==1)
{
cout<<"File opening failed";
}
else
{
while(!inputFile.eof())
{
inputFile>>student;
}
inputFile.close();
}
int income=student[0];
int gpa=student[0];
for(int i=0;i!=inputFile.eof();i++)
{
income=student[i];
gpa=student[i];
if(income>=salary && gpa<=grades)
{
cout<<" "<<income<<" "<<gpa<<endl;
}
}
cin.get();
cin.get();
return 0;
}
#include <fstream>
#include <iostream>
const int MAX_STUDENTS = 100;
int main()
{
int numberOfStudents = 0;
//Instantiate read file object
std::ifstream inputFile("Student.txt");
//Instantiate an array of income
int income[MAX_STUDENTS];
float gpa[MAX_STUDENTS];
//Check if the file is open
if(inputFile.fail() == 1)
std::cout << "\nFile opening failed!\n";
else
{
while(!inputFile.eof())
{
//Read file into class
inputFile >> income[numberOfStudents];
inputFile >> gpa[numberOfStudents];
//^^**In whatever order your data members are in**
//Check if gpa and income meet requirements
if(income[numberOfStudents] > 100000 && gpa[numberOfStudents] <= 2.3)
{
/*Output student if gpa is less than or equal to 2.3 AND
greater than 100000*/
std::cout << "\nStudent #: " << numberOfStudents + 1 << ' ' << std::endl;
std::cout << income[numberOfStudents] << ' ';
std::cout << gpa[numberOfStudents] << ' ';
std::cout << ' ' << std::endl;
}
//Increase number of students
numberOfStudents++;
}
//Close file
inputFile.close();
}
return 0;
}