Update: program shows adress of fstream instead of the text file - c++

I am about to write a program which asks the user if they want to "search or convert" a file, if they choose convert, they need to provide the location of the file.
I do not know why the program shows the address of the file instead of opening it.
Here is my first approach:
#include <fstream>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
char dateiname[64], kommando[64];
ifstream iStream;
cout << "Choose an action: " << endl <<
" s - search " << endl <<
" c - convert" << endl <<
" * - end program" << endl;
cin.getline(kommando,64,'\n');
switch(kommando[0])
{
case 'c':
cout << "Enter a text file: " << endl;
cin.getline(dateiname,64,'\n');
iStream.open("C://users//silita//desktop//schwarz.txt");
case 's': break;
case '*': return 0;
default:
cout << "Invalid command: " << kommando << endl;
}
if (!iStream)
{
cout << "The file " << dateiname << " does not exist." << endl;
}
string s;
while (getline(iStream, s)) {
while(s.find("TIT", 0) < s.length())
s.replace(s.find("TIT", 0), s.length() - s.find("TIT", 3),"*245$a");
cout << iStream << endl;
}
iStream.close();
}

At first you can't compare c-strings using ==. You must use strcmp(const char*, const char*). More info about it you can find there: http://www.cplusplus.com/reference/cstring/strcmp/
For example: if (i == "Konvertieren") must become if(!strcmp(i,"Konvertieren"))

As mentioned in Lassie's answer, you can't compare strings in this way using c or c++; just to flesh it out, however, I'll explain why.
char MyCharArr[] = "My Character Array"
// MyCharArr is now a pointer to MyCharArr[0],
// meaning it's a memory address, which will vary per run
// but we'll assume to be 0x00325dafa
if( MyCharArr == "My Character Array" ) {
cout << "This will never be run" << endl;
}
Here the if compares a pointer (MyCharArr) which will be a memory address, ie an integer, to a character array literal. Obviously 0x00325dafa != "My Character Array".
Using cstrings (character arrays), you need to use the strcmp() function which you will find in the cstring library, which will give you a number telling you "how different" the strings are, essentially giving the difference a numerical value. In this instance we are only interested in no difference, which is 0, so what we need is this:
#include <cstring>
using namespace std;
char MyCharArr[] = "My Character Array"
if( strcmp(MyCharArr,"My Character Array")==0 ) {
// If there is 0 difference between the two strings...
cout << "This will now be run!" << endl;
}
While you are not doing so in your question, If we were using c++ strings rather than character arrays, we would use the compare() method to similar affect:
#include <string>
using namespace std;
string MyString = "My C++ String"
if( MyString.compare("My C++ String")==0 ) {
// If there is 0 difference between the two strings...
cout << "This will now be run!" << endl;
}

Related

cout and String concatenation

I was just reviewing my C++. I tried to do this:
#include <iostream>
using std::cout;
using std::endl;
void printStuff(int x);
int main() {
printStuff(10);
return 0;
}
void printStuff(int x) {
cout << "My favorite number is " + x << endl;
}
The problem happens in the printStuff function. When I run it, the first 10 characters from "My favorite number is ", is omitted from the output. The output is "e number is ". The number does not even show up.
The way to fix this is to do
void printStuff(int x) {
cout << "My favorite number is " << x << endl;
}
I am wondering what the computer/compiler is doing behind the scenes.
The + overloaded operator in this case is not concatenating any string since x is an integer. The output is moved by rvalue times in this case. So the first 10 characters are not printed. Check this reference.
if you will write
cout << "My favorite number is " + std::to_string(x) << endl;
it will work
It's simple pointer arithmetic. The string literal is an array or chars and will be presented as a pointer. You add 10 to the pointer telling you want to output starting from the 11th character.
There is no + operator that would convert a number into a string and concatenate it to a char array.
adding or incrementing a string doesn't increment the value it contains but it's address:
it's not problem of msvc 2015 or cout but instead it's moving in memory back/forward:
to prove to you that cout is innocent:
#include <iostream>
using std::cout;
using std::endl;
int main()
{
char* str = "My favorite number is ";
int a = 10;
for(int i(0); i < strlen(str); i++)
std::cout << str + i << std::endl;
char* ptrTxt = "Hello";
while(strlen(ptrTxt++))
std::cout << ptrTxt << std::endl;
// proving that cout is innocent:
char* str2 = str + 10; // copying from element 10 to the end of str to stre. like strncpy()
std::cout << str2 << std::endl; // cout prints what is exactly in str2
return 0;
}

Sorting a sentence using arrays and strings

Sorry guys forewarning I suck at coding but have a big project and need help!
Input: A complete Sentence.
Output: The sorted order (ASCii Chart Order) of the sentence (ignore case.)
Output a histogram for the following categories:
1) Vowels
2) Consonants
3) Punctuation
4) Capital Letters
5) LowerCase Letters
I have no clue what to even do
Since you are vague in what your issue is, I recommend the following process:
Review Requirements
Always review the requirements (assignment). If there are items you don't understand or have the same understanding as your Customer (instructor), discuss them with your Customer.
Write a simple main program.
Write a simple main or "Hello World!" program to validate your IDE and other tools. Get it working before moving on. Keep it simple.
Here's an example:
#include <iostream>
#include <cstdlib> // Maybe necessary for EXIT_SUCCESS.
int main()
{
std::cout << "Hello World!\n";
return EXIT_SUCCESS;
}
Update program to input text & validate.
Add in code to perform input, validate the input and echo to the console.
#include <iostream>
#include <cstdlib> // Maybe necessary for EXIT_SUCCESS.
#include <string>
int main()
{
std::string sentence;
do
{
std::cout << "Enter a sentence: ";
std::getline(cin, sentence);
if (sentence.empty())
{
std::cout << "\nEmpty sentence, try again.\n\n"
}
} while (sentence.empty());
std::cout << "\nYou entered: " << sentence << "\n";
// Keep the console window open until Enter key is pressed.
std::cout << "\n\nPaused. Press Enter to finish.\n";
std::cin.ignore(100000, '\n');
return EXIT_SUCCESS;
}
Add functionality, one item at a time and test.
Add code for one simple requirement, compile and test.
After it works, make a backup.
Repeat until all requirements are implemented.
For ordering the string you can use standard c qsort function. For counting vowels, consonants, punctuation... you need a simple for loop.
Here is a working example:
#include <iostream.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int cmp(const void* pc1, const void* pc2)
{
if(*(char*)pc1 < *(char*)pc2) return -1;
if(*(char*)pc1 > *(char*)pc2) return 1;
return 0;
}
void main(int argc, char* argv[])
{
char pczInput[2000] = "A complete sentence.";
cout << endl << "Input: '" << pczInput << "'";
qsort(pczInput, strlen(pczInput), sizeof(char), cmp);
cout << endl << "Result: '" << pczInput << "'";
int iCapital = 0;
int iLowerCase = 0;
int iPunctuation = 0;
int iVowels = 0;
int iConsonants = 0;
for(unsigned int ui = 0; ui < strlen(pczInput); ++ui)
{
if(isupper(pczInput[ui])) ++iCapital;
if(islower(pczInput[ui])) ++iLowerCase;
if(ispunct(pczInput[ui])) ++iPunctuation;
if(strchr("aeiouAEIOU", pczInput[ui]) != NULL) ++iVowels;
if(strchr("bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ", pczInput[ui]) != NULL) ++iConsonants;
}
cout << endl << "Capital chars: " << iCapital;
cout << endl << "Lower case chars: " << iLowerCase;
cout << endl << "Punctuation chars: " << iPunctuation;
cout << endl << "Vowels chars: " << iVowels;
cout << endl << "Consonants chars: " << iConsonants;
cout << endl;
}
Note that I used C standard functions for counting capital, lower case and punctuation, and I had to use strchr function for counting vowels and consonants because such functions are missing in standard C library.
The output of the program is:
Input: 'A complete sentence.'
Result: ' .Acceeeeelmnnopstt'
Capital chars: 1
Lower case chars: 16
Punctuation chars: 1
Vowels chars: 7
Consonants chars: 10

C++ replace words in a string (text file)

so I worked on my program and now I am on a point where I can not find a solution. I need to replace some more signs in the fext file, for now the program only replaces "TIT" with the code number "*245$a", if I want to replace other letters the same way, the program does not change. Does anybody know how I can implement some more replacements in the text file? Let me know if there is a better option to replace more than 5 signs with another ones.
Thank you
#include <fstream>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
char dateiname[64], kommando[64];
ifstream iStream;
cout << "Choose an activity" << endl <<
" s - search " << endl <<
" c - convert" << endl <<
" * - end program" << endl;
cin.getline(kommando,64,'\n');
switch(kommando[0])
{
case 'c':
cout << "Enter a text file!" << endl;
cin.getline(dateiname,64,'\n');
iStream.open("C://users//silita//desktop//schwarz.txt");
case 's':
break;
case '*':
return 0;
default:
cout << "I can not read " << kommando << endl;
}
if (!iStream)
{
cout << "The File" << dateiname << "does not exist." << endl;
}
string s;
char o[] = "TIT";
while (getline(iStream, s))
{
while(s.find(o, 0) < s.length())
s.replace(s.find(o, 0), s.length() - s.find(o, 3),"*245$a");
cout << s << endl;
}
iStream.close();
}
You can use map in C++ STL to store multiple convert rules:
#include<map>
#include<algorithm>
using namespace std;
map<string,string> convertRules;
typedef map<string,string>::iterator MIT;
void setConvertRules(int numOfRules){
string word,code;
for(int i = 0 ; i < numOfRules; ++i){
cin>>word>>code;
//Use code as search key in order to decrypt
//If you want to encrypt, use convertrules[word] = code;
convertRules[code] = word;
}
}
To convert a file, just do as follows (some functions and classes need to be declared and implemented first, but here we mainly focus on top-level design):
/* Detailed class implementations are omitted for simplicity */
//a class to store contents of a file
class File;
//a processor to read, insert and overwrite certain file
class FileProcessor;
void FileProcessor::convert(const string &code, const string &word){
cursor == file.begin();
while(cursor != fp.end()){
_fp.convertNextLine(code,word);
}
}
File file;
FileProcessor filePcr;
int main()
const string sourceDir = "C://users//silita//desktop//schwarz.txt";
const string destDir = "C://users//silita//desktop//schwarz_decrypted.txt";
//Open a .txt file and read in its contents
if (!file.openAndReadIn(sourceDir)){
cerr << "The File" << sourceDir << "does not exist." << endl;
abort();
}
//Try to link processor to open file
if(!fp.linkTo(file)){
cerr << "Access to file" << sourceDir << "is denied." << endl;
abort();
}
//iterator is like a more safe version of C-style pointer
//the object type is a string-string pair
for(MIT it = convertRules.begin(); it != convertRules.end(); ++it){
fp.convert(it->first, it->second);
}
file.saveAs(destDir);
return 0;
}
Finally, if I would suggest you use C-style strstr function for efficiency when dealing with large files or batch processing. string::find adopts a naive sequential search startegy while strstr is implemented with the famous KMP algorithm for fast pattern match in strings, which is both efficient and thorough(can replace all matchs in one go instead of another for-loop).

line.find won't compile, line is not declared

I am a very novice programmer, and I am trying to understand the find functions for strings. At uni we are told to use c-strings, which is why I think that it isn't working. The problem comes when I compile, there is a compile error that line was not declared. This is my code:
#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
using namespace std;
int main()
{
char test[256];
char ID[256];
cout << "\nenter ID: ";
cin.getline(ID, 256);
int index = line.find(ID);
cout << index << endl;
return 0;
}
Please help, it has become really frustrating as I need to understand this function to complete my assignment :/
You're trying to use C-style strings. But find is a member of the C++ string class. If you want to use C-style strings, use functions that operate on C style strings like strcmp, strchr, strstr, and so on.
Supposing you actually input some data into test also, then one way to do it would be:
char *found = strstr(test, ID);
if ( !found )
cout << "The ID was not found.\n";
else
cout << "The index was " << (found - test) << '\n';
Because find fuction a member function string class,You should declare a string class's object. I think you will do that like this:
string test = "This is test string";
string::size_type position;
position = test.find(ID);
if (position != test.npos){
cout << "Found: " << position << endl;
}
else{
cout << "not found ID << endl;
}

getting cout output to a std::string

I have the following cout statement. I use char arrays because I have to pass to vsnprintf to convert variable argument list and store in Msg.
Is there any way we can get cout output to C++ std::string?
char Msg[100];
char appname1[100];
char appname2[100];
char appname3[100];
// I have some logic in function which some string is assigned to Msg.
std::cout << Msg << " "<< appname1 <<":"<< appname2 << ":" << appname3 << " " << "!" << getpid() <<" " << "~" << pthread_self() << endl;
You can replace cout by a stringstream.
std::stringstream buffer;
buffer << "Text" << std::endl;
You can access the string using buffer.str().
To use stringstream you need to use the following libraries:
#include <string>
#include <iostream>
#include <sstream>
You can use std::stringstream
http://www.cplusplus.com/reference/iostream/stringstream/
If you can change the code then use ostringstream (or stringstream) instead of cout.
If you cannot change the code and want to "capture" what is being output you can redirect your output or pipe it.
It may then be possible for your process to read the file or get the piped information through shared memory.
#include <stdio.h>
#include <iostream>
#include <string>
#include <sstream>
// This way we won't have to say std::ostringstream or std::cout or std::string...
using namespace std;
/** Simulates system specific method getpid()... */
int faux_getpid(){
return 1234;
}
/** Simulates system specific method pthread_self()... */
int faux_pthread_self(){
return 1111;
}
int main(int argc, char** argv){
// Create a char[] array of 100 characters...
// this is the old-fashioned "C" way of storing a "string"
// of characters..
char Msg[100];
// Try using C++-style std::string rather than char[],
// which can be overrun, leading to
// a segmentation fault.
string s_appname1;
// Create old-fashioned char[] array of 100 characters...
char appname2[100];
// Create old-fashioned char[] array of 100 characters...
char appname3[100];
// Old-fashioned "C" way of copying "Hello" into Msg[] char buffer...
strcpy(Msg, "Hello");
// C++ way of setting std::string s_appname equal to "Moe"...
s_appname1 = "Moe";
// Old-fashioned "C" way of copying "Larry" into appname2[] char buffer...
strcpy(appname2, "Larry");
// Old-fashioned "C" way of copying "Shemp" into appname3[] char buffer...
strcpy(appname3, "Shemp");
// Declare le_msg to be a std::ostringstream...
// this allows you to use the C++ "put-to" operator <<
// but it will "put-to" the string-stream rather than
// to the terminal or to a file...
ostringstream le_msg;
// Use put-to operator << to "write" Msg, s_appname1, s_appname2, etc...
// to the ostringstream...not to the terminal...
le_msg << Msg << " "<< s_appname1 <<":"<< appname2 << ":" << appname3 << " " << "!" << faux_getpid() <<" " << "~" << faux_pthread_self();
// Print the contents of le_msg to the terminal -- std::cout --
// using the put-to operator << and using le_msg.str(),
// which returns a std::string.
cout << "ONE: le_msg = \"" << le_msg.str() << "\"..." << endl;
// Change contents of appname3 char[] buffer to "Curly"...
strcpy(appname3, "Curly");
// Clear the contents of std::ostringstream le_msg
// -- by setting it equal to "" -- so you can re-use it.
le_msg.str("");
// Use put-to operator << to "write" Msg, s_appname1, s_appname2, etc...
// to the newly cleared ostringstream...not to the terminal...
// but this time appname3 has been set equal to "Curly"...
le_msg << Msg << " "<< s_appname1 <<":"<< appname2 << ":" << appname3 << " " << "!" << faux_getpid() <<" " << "~" << faux_pthread_self();
// Print the new contents of le_msg to the terminal using the
// put-to operator << and using le_msg.str(),
// which returns a std::string.
cout << "TWO: le_msg = \"" << le_msg.str() << "\"..." << endl;
// This time, rather than using put-to operator << to "write"
// to std::ostringstream le_msg, we'll explicitly set it equal
// to "That's all Folks!"
le_msg.str("That's all Folks!");
// Print the new contents of le_msg "That's all Folks!" to
// the terminal via le_msg.str()
cout << "THREE: le_msg = \"" << le_msg.str() << "\"..." << endl;
// Exit main() with system exit value of zero (0), indicating
// success...
return 0;
}/* main() */
OUTPUT:
ONE: le_msg = "Hello Moe:Larry:Shemp !1234 ~1111"...
TWO: le_msg = "Hello Moe:Larry:Curly !1234 ~1111"...
THREE: le_msg = "That's all, folks!"...