How to convert a text file from Windows to Unix - c++

When converting from Unix to Windows, I get the correct output; however, when going from Windows to Unix I get some strange output. I thought all I had to allow for was the removal of the carriage return, '\r'. This isn't working though. When I open the text file after running the code, I get some strange results, the first line is correct, and then all hell breaks lose.
int main( )
{
bool windows = false;
char source[256];
char destination[256]; // Allocate the max amount of space for the filenames.
cout << "Please enter the name of the source file: ";
cin >> source;
ifstream fin( source, ios::binary );
if ( !fin ) // Check to make sure the source file exists.
{
cerr << "File " << source << " not found!";
getch();
return 1;
}//endif
cout << "Please enter the name of the destination file: ";
cin >> destination;
ifstream fest( destination );
if ( fest ) // Check to see if the destination file already exists.
{
cout << "The file " << destination << " already exists!" << endl;
cout << "If you would like to truncate the data, please enter 'Y', "
<< "otherwise enter 'N' to quit: ";
char answer = char( getch() );
if ( answer == 'n' || answer == 'N' )
{
return 1;
}//endif
}//endif
clrscr(); // Clear screen for neatness.
ofstream fout( destination, ios::binary );
if ( !fout.good() ) // Check to see if the destination file can be edited.
{
cout << destination << "could not be opened!" << endl;
getch();
return 1;
}//endif
// Open the destination file in binary mode.
fout.open( destination, ios::binary );
char ch = fin.get(); // Set ch to the first char in the source file.
while ( !fin.eof() )
{
if ( ch == '\x0D' ) // If ch is a carriage return, then the source file
{ // must be in a windows format.
windows = true;
}//endif
if ( windows == true )
{
ch = fin.get(); // Advance ch, so that at the bottom of the loop, the
}//endif // carriage return is not coppied into the new file.
if ( windows == false )
{
if ( ch == '\x0A' ) // If the file is in the Unix format..
{
fout.put( '\x0D' ); // When a new line is found, output a carriage
}//endif // return.
}//endif
fout.put( ch );
ch = fin.get();
}//endwh
if ( windows == true )
{
fout.put( '\x0A' );
}//endif
fout.close();
fin.close(); // Close yer files.
if ( windows == true ) // A little output for user-friendly-ness.
{
cout << "The contents of " << source << " have been coppied to "
<< destination << " and converted to Unix format." << endl;
}else{
cout << "The contents of " << source << " have been coppied to "
<< destination << " and converted to Windows format." << endl;
}//endif
cout << "Enter any key to quit.." << endl;
getch();
return 0;
}//endmn

*If* you only need to convert simple ascii (and perhaps utf-8) text files, you could read the source file line-by-line in a loop in translated mode (handles newlines for you enough for this case) with non-member getline() and then output the lines to the output file while inserting \n or \r\n after each line except the last.
Then, you can remove the original file and rename the temp file to have the original file's name. Or, if you want, you can instead push_back the lines into a vector<string>. Then, you could close the input handle to the file, do ofstream out("filename", ios_base::trunc) and write the elements of the vector to the file while separating them by the newlines you want.
It all depends on your requirements.
The following is an example with minimal error handling. But, it's really only the FOR loop and reading line-by-line that I want to show here as a different way of doing things.
convert_file.exe "test.txt" "linux"
convert_file.exe "test.txt" "win"
#include <iostream>
#include <string>
#include <fstream>
#include <ostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
int main(int argc, char* argv[]) {
if (argc != 3) {
cerr << "Usage: this.exe file_to_convert newline_format(\"linux\" or \"win\")" << endl;
return EXIT_FAILURE;
}
string fmt(argv[2]);
if (fmt != "linux" && fmt != "win") {
cerr << "Invalid newline format specified" << endl;
return EXIT_FAILURE;
}
ifstream in(argv[1]);
if (!in) {
cerr << "Error reading test.txt" << endl;
return EXIT_FAILURE;
}
string tmp(argv[1]);
tmp += "converted";
ofstream out(tmp.c_str(), ios_base::binary);
if (!out) {
cerr << "Error writing " << tmp << endl;
return EXIT_FAILURE;
}
bool first = true;
for (string line; getline(in, line); ) {
if (!first) {
if (fmt == "linux") {
out << "\n";
} else {
out << "\r\n";
}
}
out << line;
first = false;
}
in.close();
out.close();
if (remove(argv[1]) != 0) {
cerr << "Error deleting " << argv[1] << endl;
return EXIT_FAILURE;
}
if (rename(tmp.c_str(), argv[1]) != 0) {
cerr << "Error renaming " << tmp << " to " << argv[1] << endl;
return EXIT_FAILURE;
}
}
As others have said though, there are already utilities (including text editors like Notepadd++) that do newline conversion for you. So, you don't need to implement anything yourself unless you're doing this for other reasons (you didn't specify).

Don't worry about checking for windows in the loop. Simply check for a carriage return. Set a variable 'carriage_return.' Next iteration, if 'carriage-return' and ch != linefeed, simply insert a linefeed. Then reset the carriage_return variable to false. It's a very simple and basic rule which won't send you wrong.
bool carriage_return = false;
const char linefeed = '\n'; // Is it? I forget.
const char cr = '\r'; // I forget again. Too late to check.
char ch = fin.get();
if (ch == cr) carriage_return = true;
while (!fin.eof()){
if (carriage_return) { // Check if we already have a newline
if (ch != linefeed) { // If we have a newline previously, we need a linefeed. If it's already there just leave it, if it isn't there put it in
fout.put(linefeed);
}
if (ch != cr) carriage_return = false; // Reset the carriage-return flag *if* we don't have another carriage return. This handles multiple empty lines in an easy way for us.
}
fout.put(ch);
ch = fin.get();
}

I have re-edit your code and it works fine for me..
Hope this helps !
#include <iostream>
#include <fstream>
#include <iostream>
#include<stdio.h>
using namespace std;
int main( )
{
bool windows = false;
char source[256];
char destination[256]; // Allocate the max amount of space for the filenames.
cout << "Please enter the name of the source file: ";
cin >> source;
ifstream fin( source, ios::binary );
if ( !fin ) // Check to make sure the source file exists.
{
cerr << "File " << source << " not found!";
return 1;
}//endif
cout << "Please enter the name of the destination file: ";
cin >> destination;
ifstream fest( destination );
if ( fest ) // Check to see if the destination file already exists.
{
cout << "The file " << destination << " already exists!" << endl;
cout << "If you would like to truncate the data, please enter 'Y', "
<< "otherwise enter 'N' to quit: ";
char answer;
cin >> answer;
if ( answer == 'n' || answer == 'N' )
{
return 1;
}
}
//clrscr();
ofstream fout( destination);
if ( !fout.good() )
{
cout << destination << "could not be opened!" << endl;
return 1;
}
char ch = fin.get();
while (!fin.eof())
{
if ( ch == '\r' )
{
windows = true;
}
if ( ch == '\n' && windows == false ) // If the file is in the Unix format..
{
// Don't do anything here
}
fout.put( ch );
cout << ch; // For Debugging purpose
ch = fin.get();
}
fout.close();
fin.close();
if ( windows == true ) // A little output for user-friendly-ness.
{
cout<<endl;
cout << "The contents of " << source << " have been coppied to "
<< destination << " and converted to Unix format." << endl;
}else{
cout << "The contents of " << source << " have been coppied to "
<< destination << " and converted to Windows format." << endl;
}//endif
cout << "Enter any key to quit.." << endl;
return 0;
}

Did you make sure you're reading in the data in the right format and saving it in the right format?
Trying to work with a different character encoding and just 'reading' it in leads to very bad things :|
And you then also have to account for different replacements that need to be done.
This may help link

Related

readFile function not working on second iteration with different argument - c++

I've written a readFile function for a project I'm working on. I call it once, load in a file and read in it's contents - works fine
However, when I try to load it a second time, attempting to change the file name - it loads it in, saves it to a static string 'path' that I access in a different function - but then the function is not printing the data
The question is, how do I change the file name, and read it in successfully on the second iteration? The part that has me stumped is that it works once, but not twice
Ive attempted to use cin.ignore(); cin.clear(); cin.sync() on the second iteration of fileName function - but none of them allow a separate file to be read successfully.
Minimum Reproducible Example:
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <vector>
#include <sstream>
#include <iomanip>
#include <iostream>
using namespace std;
static string path;
string opt;
void readFile();
int fileName();
void menu() { // put in while loop - while True
cout << "----------------------" << endl;
cout << "R(ead) -" << "Read File" << endl;
cout << "F(ile) -" << "Set Filename" << endl;
cout << "\nPlease select from the above options" << endl;
cin >> opt;
cout << "\nInput entered: " << opt << endl;
if (opt == "R") {
readFile();
}
if (opt == "F") {
fileName();
}
}
void readFile() { // doing this twice
ifstream readFile;
readFile.open(path);
if (!readFile.is_open()) {
cout << "Could not read file" << endl;
}
string str;
int i = 0;
while (getline(readFile, str))
{
if (str[0] != '/')
{
cout << "DEBUG: Line is - " << str << endl;
}
}
readFile.clear();
readFile.close();
menu();
}
int fileName() {
cout << "File path: ";
if (path != "") {
cin.ignore();
cin.clear();
cin.sync();
}
getline(cin, path);
ifstream file(path.c_str());
if (!file) {
cout << "Error while opening the file" << endl;
return 1;
}
cout << "(File loaded)" << endl;
cout << "Path contains: " << path << endl;
file.clear();
file.close();
menu();
}
int main()
{
fileName();
}
Sample text, saved as txt file and read in using path:
Data1.txt
// standard test file
123,Frodo inc,2006, lyons,"1,021,000.16",0.0,
U2123,Sam Inc,2006, lyons,"21,600.00",13.10,123
A721,Merry Inc,2604, Kingston,"21,600.10",103.00,
U2122,Pippin Inc,2612, reid,"21,600.00",0
U1123,Huckelberry corp,2612, Turner,"21,600.00",13.10,
Data2.txt
7101003,Mike,23 boinig road,2615,48000,12000,0
7201003,Jane Philips,29 boinig cresent,2616,47000,12000,0
7301003,Philip Jane,23 bong road,2615,49000,000,0
7401004,Peta,23 bong bong road,2615,148000,19000,0
7101205,Abdulla,23 Station st,2615,80000,21000,0
The problem comes from reading in one, and trying to read in the other after the first has been executed.
Enter Filename
Hit Readfile
Return to menu, hit Set Filename
Change to Data2.txt
Readfile again. Not working
My tutor told me "That's not how functions work in c++" but didn't elaborate further, and is unavailable for contact.
In general, do not use global variables. The path variable should be passed as a parameter, not kept as a global variable altered between function calls, as this leads to many side effects and is the source of countless bugs. See the following refactoring:
void menu() { // put in while loop - while True
while(true)
{
//Keep this as a local variable!
std::string opt;
std::string filename;
cout << "----------------------\n";
cout << "R(ead) -" << "Read File\n";
cout << "F(ile) -" << "Set Filename\n";
cout << "\nPlease select from the above options\n";
cin >> opt;
cout << "\nInput entered: " << opt << '\n';
if (opt == "R") {
readFile(filename);
}
if (opt == "F") {
filename = getFileName();
}
}
}
void readFile(const std::string & filename) {
ifstream readFile;
readFile.open(filename);
if (!readFile.is_open()) {
cout << "Could not read file " << filename << '\n';
}
string str;
int i = 0;
while (getline(readFile, str))
{
if (str[0] != '/')
{
cout << "DEBUG: Line is - " << str << '\n';
}
}
readFile.close();
//just return to get back to menu
return;
}
std::string getFileName() {
cout << "File path: ";
std::string path;
getline(cin, path);
ifstream file(path.c_str());
if (!file) {
cout << "Error while opening the file" << '\n';
//Instead of returning an error code use an exception preferably
}
cout << "(File loaded)" << '\n';
cout << "Path contains: " << path << '\n';
file.close();
return path;
}
Other notes:
Ideally, do input in output in just one function, not all three as it gets confusing exactly what each function is responsible for.
If you want something to hold a file and print the contents, you can use an class.
The file is checked if it is openable twice, not really any reason to do this just delegate that responsibility to one function.
One of the best things about C++ is RAII and deterministic lifecycles for objects and primitives - use it!! Do not give everything a long life with global variables - use smart parameters and return values instead.

C++ Function to Search for A Numeric Value in a File

I have an assignment where I must create a function that takes a filename as a parameter, opens the file, asks a user to enter a value to be searched for, and then searches the file for that value. The file I was given to use for this assignment is a file with a list of revenue and expense values. I have tried just about everything and keep receiving the "value not found" prompt even when I enter a value that i know is in the file.
The code is
void numberSearch(string fileName)
{
string searchVal;
cout << "\nWhat value would you like to search for?\n";
cin.ignore();
getline(cin, searchVal);
ifstream file; //create input file object that will be read from
file.open(fileName); //"ifstream file (fileName)"
if (!file)
{
cout << "\nUnable to open file.\n";
exit(1);
}
string words;
int curLine = 0; //file line counter
while (getline(file, words))
{
++curLine; //counts each line in the file
if (words.find(searchVal) != string::npos)
{
cout << "\nLine " << curLine << " contains " << searchVal << endl;
file.close();
return;
}
else
{
cout << "\nThe value " << searchVal << " was not found.\n";
file.close();
return;
}
}
}
Any help is greatly appreciated
You need to put the else part out side of while loop. Otherwise your function will only search for the first line.
I was bored so I decided to do it too. I'll post mine, even though its already solved. (upvoted the question for the fun of solving ;) )
using namespace std;
int testfile(string filename, int &line, int &character)
{
ifstream is(filename, std::ios::in);
if (!is.is_open()) return 1; //1 = no file
cout << "Search for what value?" << endl;
string value;
cin >> value;
string buf;
while (getline(is,buf))
{
++line;
if (buf.find(value) != buf.npos)
{
character=buf.find(value); //the part that got lost in edit
return 0; //value found, returning 0
}
}
return 2; //return 2 since no value was found
}
which is called under main():
main()
{
int line=0; //what line it is
int character=0; //what character on that line
int result=testfile("test.txt", line, character); //debug+passing as reference
if (result == 1)cout << "could not find file" << endl;
if (result == 2)cout << "could not find value" << endl;
if (result == 0)
cout << "found at line# " << line << " character# " << character << endl;
return 0;
}
Passing values by reference lets us make use of them in our original scope. Therefore the function can both give errors for debugging, and allow useful results for our scopes purpose.
Closing the fstream is not necessary, as leaving the scope will take care of that for us: see here
Hehe, almost like being at school ;)

getline and testing EOF at once

I would like to ask about my problem I tried to read Getline and EOF Question but did not help.
Problem is I have no idea where could be mistake here:
Is there some problem with used function ( getline or checking EOF ) ?
If there is no text in text.txt file it says there something was found. But I have no idea why or where I made a mistake ...
What I want is: Search for string and if there is no text in txt file I want it to says EOF or something. It still says - even if file is empty - string I was looking for was found in line one , position one - for example
I am puting there code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int openFile(void);
int closeFile(void);
int getTime(void);
int findTime();
int findDate();
int stringFind(string);
bool getOneLine(void);
string what;
bool ifound = false;
string foundstring;
string filename ;
fstream inputfile;
string sentence ;
size_t found ;
string foundTime ;
string foundDate ;
bool timeIsHere = false;
bool dateIsHere = false;
int iterTime = 0;
int iterDate = 0;
int line = 0;
int main (void){
sentence.clear();
cout << " Enter the file name:" << endl;
openFile();
while (getOneLine() != false) {
stringFind("Time");
}
cout << "END OF PROGRAM" << endl;
system("PAUSE");
///getTime();
closeFile();
system("PAUSE");
}
int closeFile(void) {
inputfile.close();
cout << " File: " << filename << " - was closed...";
return 0;
}
int openFile(void) {
cout << " Insert file name in program directory or full path to desired file you want to edit:"<<endl;
cout << " Do not use path with a space in directory address or filename ! " << endl;
cout<<" ";
getline(cin, filename);
inputfile.open(filename, ios::in);
cout <<" file_state: " << inputfile.fail();
if (inputfile.fail() == 1) {
cout << " - Cannot open your file" << endl;
}
else cout << " - File was openned sucesfully"<< endl;
return 0;
}
int stringFind(string what) {
cout << " I am looking for:" << what << endl;
found = what.find(sentence);
if (found == string::npos) {
cout << " I could not find this string " << endl;
}
else if(found != string::npos){
cout << " substring was found in line: " << line + 1 << " position: " << found + 1 << endl << endl;
ifound = true;
foundstring = sentence;
}
return 0;
}
bool getOneLine(void) {
if (inputfile.eof()) {
cout << "END OF FILE" << endl << endl;
return false;
}
else{
getline(inputfile, sentence);
cout << "next sentence is: "<< sentence << endl;
return true;
}
}
I am newbie and I have no one to ask - personally . I tried to edit While cycle and IF's to make sure that I did not make a serious mistake but I have no idea.
I tried it with for example sample.txt and this file was empty.
Always test whether input succeeded after the read attempt! The stream cannot know what you are attempting to do. It can only report whether the attempts were successful so far. So, you'd do something like
if (std::getline(stream, line)) {
// deal with the successful case
}
else {
// deal with the failure case
}
In the failure case you might want to use use eof() to determine whether the failure was due reaching the end of the stream: Having reached the end of file and, thus, std::ios_base:eofbit being set is often not an error but simply the indication that you are done. It may still be an error, e.g., when it is known how many lines are to be read but fewer lines are obtained.
Correct way to use getline() and EOF checking would be like this:
bool getOneLine(void) {
if (getline(inputfile, sentence)) {
cout << "next sentence is: "<< sentence << endl;
return true;
}
if (inputfile.eof())
cout << "EOF reached" << endl;
else
cout << "Some IO error" << endl;
return false;
}
You have one mistake here:
found = what.find(sentence);
You are seeking inside of what for the sentence. If sentence is empty, it will be found.
Change it to
found = sentence.find(what);
You should definitivly learn how to use a debugger. That way you would find such issues pretty fast!

FASTA reader written in C++?

Let me start off by stating that I am a beginner in C++. Anyways, the FASTA format goes as follows:
Any line starting with a '>' indicates the name/id of the gene sequence right below it. There is a gene sequence right below the id. This gene sequence can be 1 or multiple lines.
So... what I want to do is print: id << " : " << gene_sequence << endl;
Here is my code:
#include <iostream>
#include <fstream>
int main(int argc, char **argv) {
if (argc < 2) {
std::cerr << " Wrong format: " << argv[0] << " [infile] " << std::endl;
return -1;
}
std::ifstream input(argv[1]);
if (!input.good()) {
std::cerr << "Error opening: " << argv[1] << " . You have failed." << std::endl;
return -1;
}
std::string line, id, DNA_sequence;
while (std::getline(input, line).good()) {
if (line[0] == '>') {
id = line.substr(1);
std::cout << id << " : " << DNA_sequence << std::endl;
DNA_sequence.clear();
}
else if (line[0] != '>'){
DNA_sequence += line;
}
}
}
For the second argument inputted into the command line, here is the content of my file:
>DNA_1
GATTACA
>DNA_2
TAGACCA
TAGACCA
>DNA_3
ATAC
>DNA_4
AT
Please copy and paste into text file.
After this has been done, and the code has been executed, I want to point out the problem. The code skips inputting the sequence of DNA_1 into its correct respective place, and instead placing DNA_1 's sequence into DNA_2. The results get pushed forward 1 as a result. Any assistance or tips would be greatly appreciated?
As I've said before, I am new to C++. And the semantics are quite hard to learn compared to Python.
I see a few problems with your code.
First you loop on std::ifstream::good() which doesn't work because it won't allow for End Of File (which happens even after a good read).
Then you access line[0] without checking if the line is empty which could cause a seg-fault.
Next you output the "previous line" before you have even collected it.
Finally you don't output the final line because the loop terminates when it doesn't find another >.
I added comments to my corrections to your code:
#include <iostream>
#include <fstream>
int main(int argc, char **argv) {
if (argc < 2) {
std::cerr << " Wrong format: " << argv[0] << " [infile] " << std::endl;
return -1;
}
std::ifstream input(argv[1]);
if (!input.good()) {
std::cerr << "Error opening: " << argv[1] << " . You have failed." << std::endl;
return -1;
}
std::string line, id, DNA_sequence;
// Don't loop on good(), it doesn't allow for EOF!!
// while (std::getline(input, line).good()) {
while (std::getline(input, line)) {
// line may be empty so you *must* ignore blank lines
// or you have a crash waiting to happen with line[0]
if(line.empty())
continue;
if (line[0] == '>') {
// output previous line before overwriting id
// but ONLY if id actually contains something
if(!id.empty())
std::cout << id << " : " << DNA_sequence << std::endl;
id = line.substr(1);
DNA_sequence.clear();
}
else {// if (line[0] != '>'){ // not needed because implicit
DNA_sequence += line;
}
}
// output final entry
// but ONLY if id actually contains something
if(!id.empty())
std::cout << id << " : " << DNA_sequence << std::endl;
}
Output:
DNA_1 : GATTACA
DNA_2 : TAGACCATAGACCA
DNA_3 : ATAC
DNA_4 : AT
You're storing the new id before printing the old one:
id = line.substr(1);
std::cout << id << " : " << DNA_sequence << std::endl;
Swap the lines around for proper order. You probably also want to check if you have any id already present to skip the first entry.
working implementation is here
https://rosettacode.org/wiki/FASTA_format#C.2B.2B
only corrected
while( std::getline( input, line ).good() ){
to
while( std::getline( input, line ) ){
Code
#include <iostream>
#include <fstream>
int main( int argc, char **argv ){
if( argc <= 1 ){
std::cerr << "Usage: "<<argv[0]<<" [infile]" << std::endl;
return -1;
}
std::ifstream input(argv[1]);
if(!input.good()){
std::cerr << "Error opening '"<<argv[1]<<"'. Bailing out." << std::endl;
return -1;
}
std::string line, name, content;
while( std::getline( input, line ) ){
if( line.empty() || line[0] == '>' ){ // Identifier marker
if( !name.empty() ){ // Print out what we read from the last entry
std::cout << name << " : " << content << std::endl;
name.clear();
}
if( !line.empty() ){
name = line.substr(1);
}
content.clear();
} else if( !name.empty() ){
if( line.find(' ') != std::string::npos ){ // Invalid sequence--no spaces allowed
name.clear();
content.clear();
} else {
content += line;
}
}
}
if( !name.empty() ){ // Print out what we read from the last entry
std::cout << name << " : " << content << std::endl;
}
return 0;
}
input:
>Rosetta_Example_1
THERECANBENOSPACE
>Rosetta_Example_2
THERECANBESEVERAL
LINESBUTTHEYALLMUST
BECONCATENATED
output:
Rosetta_Example_1 : THERECANBENOSPACE
Rosetta_Example_2 : THERECANBESEVERALLINESBUTTHEYALLMUSTBECONCATENATED

Issue regarding size_t

If you go in my post history you'll see that i'm trying to develop an interpreter for a language that i'm working on. I want to use size_t using two different codes, but they all return nothing.
Here is the post of what i was trying: http://stackoverflow.com/questions/1215688/read-something-after-a-word-in-c
When i try to use the file that i'm testing it returns me nothing. Here is the sample file(only a print function that i'm trying to develop in my language):
print "This is a print function that i'm trying to develop in my language"
But remember that this is like print in Python, what the user type into the quotes(" ") is what have to be printed to all, remember that the user can choose what put into the quotes, then don't put something like a simple cout, post something that reads what is inside the quotes and print it to all. But here is the two test codes to do this, but all of they don't returns nothing to me:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
int main( int argc, char* argv[] )
{
// Error Messages
string extension = argv[ 1 ];
if(argc != 2)
{
cout << "Error syntax is incorrect!\nSyntax: " << argv[ 0 ] << " <file>\n";
return 0;
}
if(extension[extension.length()-3] != '.')
{
cout << "Extension not valid!" << endl;
cout << "Default extension *.tr" << endl;
return 0;
}
if(extension[extension.length()-2] != 't')
{
cout << "Extension not valid!" << endl;
cout << "Default extension *.tr" << endl;
return 0;
}
if(extension[extension.length()-1] != 'r')
{
cout << "Extension not valid!" << endl;
cout << "Default extension *.tr" << endl;
return 0;
}
// End of the error messages
ifstream file(argv[ 1 ]);
if (!file.good()) {
cout << "File " << argv[1] << " does not exist.\n";
return 0;
}
string linha;
while (!file.eof())
{
getline(file, linha);
if (linha == "print")
{
size_t idx = linha.find("\""); //find the first quote on the line
while ( idx != string::npos ) {
size_t idx_end = linha.find("\"",idx+1); //end of quote
string quotes;
quotes.assign(linha,idx,idx_end-idx+1);
// do not print the start and end " strings
cout << "quotes:" << quotes.substr(1,quotes.length()-2) << endl;
//check for another quote on the same line
idx = linha.find("\"",idx_end+1);
}
}
}
return 0;
}
The second:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
int main( int argc, char* argv[] )
{
// Error Messages
string extension = argv[ 1 ];
if(argc != 2)
{
cout << "Error syntax is incorrect!\nSyntax: " << argv[ 0 ] << " <file>\n";
return 0;
}
if(extension[extension.length()-3] != '.')
{
cout << "Extension not valid!" << endl;
cout << "Default extension *.tr" << endl;
return 0;
}
if(extension[extension.length()-2] != 't')
{
cout << "Extension not valid!" << endl;
cout << "Default extension *.tr" << endl;
return 0;
}
if(extension[extension.length()-1] != 'r')
{
cout << "Extension not valid!" << endl;
cout << "Default extension *.tr" << endl;
return 0;
}
// End of the error messages
ifstream file(argv[ 1 ]);
if (!file.good()) {
cout << "File " << argv[1] << " does not exist.\n";
return 0;
}
string linha;
while (!file.eof())
{
getline(file, linha);
if (linha == "print")
{
string code = " print \" hi \" ";
size_t beg = code.find("\"");
size_t end = code.find("\"", beg+1);
// end-beg-1 = the length of the string between ""
cout << code.substr(beg+1, end-beg-1);
}
}
return 0;
}
And here is what is printed in the console:
ubuntu#ubuntu-laptop:~/Desktop/Tree$ ./tree test.tr
ubuntu#ubuntu-laptop:~/Desktop/Tree$
Like i said, it prints me nothing.
See my post in D.I.C.: http://www.dreamincode.net/forums/showtopic118026.htm
Thanks,
Nathan Paulino Campos
Your problem is the line
if (linha == "print")
which assumes the entire line just read in is "print", not that the line STARTS with print.
Also, why would you use 3 separate checks for a .tr extension, vs. just checking the end of the filename for ".tr"? (You should also be checking that argv[1] is long enough before checking substrings...)
getline(file, linha) will read an entire line from the file, so linha never be equal to print.