Sorry, the thread title should read "File paths with spaces"

Hello everyone. I am finalizing this little shift cipher program that reads a plain text file line by line, encrypts it, and writes it to a cipher text file. I'm just having difficulty when a user enters file paths with spaces. When this happens with the first file path request, the next one is skipped, and the user is asked to enter the shift value. Any help would be very appreciated.

#include <cstdlib>
#include <iostream> 
#include <fstream>

using namespace std;

int main(int argc, char *argv[]){
    
    int shiftValue = 0;
    string plainLine = "";
    string inputPath = "";
    string outputPath= "";
    
    ifstream plainText(inputPath.c_str());
    ofstream cipherText(outputPath.c_str());
   
    cout << "Input Path: ";
    cin >> inputPath;
    cout << endl;
    
    cout << "Output Path: ";    
    cin >> outputPath;
    cout << endl;
   
    cout << "Shift Value = ";
    cin >> shiftValue;
    cout << endl;
    
    while (!plainText.eof()){
    
    int lineLength;
    
    getline(plainText, plainLine);
    lineLength = plainLine.length();  
    
    int decimalValue[lineLength];
    char cipherLine[lineLength];
   
    for (int i=0; i<=lineLength; i++){
        decimalValue[i] = (int)plainLine[i] + shiftValue; 
        cipherLine[i] = (char)decimalValue[i];
        cipherText << cipherLine[i];  
        }   
  
    cipherText << endl;
    }
  
    system("PAUSE");
    return EXIT_SUCCESS;
}

Recommended Answers

All 7 Replies

The >> operator is default delimited by whitespace. If your strings need to contain whitespace, use getline instead.

FYI:

>ifstream plainText(inputPath.c_str());
>ofstream cipherText(outputPath.c_str());

This won't do jack because inputPath and outputPath are presently empty strings. You need to open the file after figuring out what the path is. :icon_rolleyes:

>while (!plainText.eof()){
This is a bad idea. The eof member function only returns true after reading past end-of-file. In other words, your loop will probably run once more than expected. Because getline returns a stream reference, and stream references have a conversion for the stream state, you can do this to fix the problem:

while ( getline ( plainText, plainLine ) ) {
  // ...
}
commented: Thank you!!!! +1

The >> operator is default delimited by whitespace. If your strings need to contain whitespace, use getline instead.

Ahh, thank you very much for your quick reply.

Thanks Narue for your help. Very appreciated. I made the changes you suggested. Everything compiles and the file path inputs work. However, the changes made to the while loop condition dont seem to work as nothing is being written to my cipher.txt output. And when I go back to the old while conditions, the program freezes.
Thank you. Updated code below.

#include <cstdlib>
#include <iostream> 
#include <fstream>

using namespace std;

int main(int argc, char *argv[]){
    
    int shiftValue = 0;
    string plainLine = "";
    string inputPath = "";
    string outputPath= "";
    
    cout << "Input Path: ";
    getline(cin, inputPath);
    cout << endl;
    ifstream plainText(inputPath.c_str());
    
    cout << "Output Path: ";    
    getline(cin, outputPath);
    cout << endl;
    ofstream cipherText(outputPath.c_str());
   
    cout << "Shift Value = ";
    cin >> shiftValue;
    cout << endl;
    
    while (getline(plainText, plainLine)){
    
    int lineLength;
    
    getline(plainText, plainLine);
    lineLength = plainLine.length();  
    
    int decimalValue[lineLength];
    char cipherLine[lineLength];
   
    for (int i=0; i<=lineLength; i++){
        decimalValue[i] = (int)plainLine[i] + shiftValue; 
        cipherLine[i] = (char)decimalValue[i];
        cipherText << cipherLine[i];  
        }   
  
    cipherText << endl;
    }
  
    system("PAUSE");
    return EXIT_SUCCESS;
}

I didn't try to compile the code but...
First you did not change the while as narue said

while ( getline ( plainText, plainLine ) ) {

instead of

while (getline(plainText, plainLine)){

Second should try

string plainLine, inputPath, outputPath;//all in one

And third:

ofstream cipherText(outputPath.c_str());
ofstream cipherText(outputPath.c_str());

No ios::in nor ios::out... I belive your stream does nothing

>First you did not change the while as narue said
>while ( getline ( plainText, plainLine ) ) {
>instead of
>while (getline(plainText, plainLine)){

Um...what? Do you really think a few extra spaces will make any significant difference?

>Second should try
>string plainLine, inputPath, outputPath;//all in one

I would argue otherwise, but matters of style are very subjective.

>No ios::in nor ios::out... I belive your stream does nothing
And I believe you don't know what you're talking about. ofstream is derived from fstream and defaults to ios_base::out for the second constructor argument.

Can someone try it out on their compiler to see if maybe it is my machine/compiler.

You just need to have a .txt file to give it with some text from a news article perhaps. Please make sure its the updated code.

Thanks.

The code from post #4 ran on my machine and produced an output file.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.