user3808269
user3808269

Reputation: 1351

Why do I obtain this strange character?

Why does my C++ program create the strange character shown below in the pictures? The picture on the left with the black background is from the terminal. The picture on the right with the white background is from the output file. Before, it was a "\v" now it changes to some sort of astrological symbol or symbol to denote males. 0_o This makes no sense to me. What am I missing? How can I have my program output just a backslash v?

enter image description here enter image description here

Please see my code below:

// SplitActivitiesFoo.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <fstream>

using namespace std;

int main()
{
    string s = "foo:bar-this-is-more_text@\venus  \"some more text here to read.\"";
    vector<string> first_part;
    fstream outfile;
    outfile.open("out.foobar");

    for (int i = 0; i < s.size(); ++i){

        cout << "s[" << i << "]: " << s[i] << endl;
        outfile << s[i] << endl;
    }



    return 0;
}

Also, assume that I do not want to modify my string 's' in this case. I want to be able to parse each character of the string and work around the strange character somehow.This is because in the actual program the string will be read in from a file and parsed then sent to another function. I guess I could figure out a way to programmatically add backslashes...

Upvotes: 3

Views: 1017

Answers (3)

paddy
paddy

Reputation: 63461

How can I have my program output just a backslash v?

If you want a backslash, then you need to escape it: "@\\venus".

This is required because a backslash denotes that the next character should be interpreted as something special (note that you were already using this when you wanted double-quotes). So the compiler has no way of knowing you actually wanted a backslash unless you tell it.

A literal backslash character therefore has the syntax \\. This is the case in both string literals ("\\") and character literals ('\\').

Why does my C++ program create the strange character shown below in the picture?

Your string contains the \v control character (vertical tab), and the way it's displayed is dependent on your terminal and font. It looks like your terminal is using symbols from the traditional MSDOS code page.

I found an image for you here, which shows exactly that symbol for the vertical tab (vt) entry at value 11 (0x0b):

ASCII table

Also, assume that I do not want to modify my string 's' in this case. I want to be able to parse each character of the string and work around the strange character somehow.

Well, I just saw you add the above part to your question. Now you're in difficult territory. Because your string literal does not actually contain the character v or any backslashes. It only appears that way in code. As already said, the compiler has interpreted those characters and substituted them for you.

If you insist on printing v instead of a vertical tab for some crazy reason that is hopefully not related to an XY Problem, then you can construct a lookup-table for every character and then replace undesirables with something else:

char lookup[256];
std::iota( lookup, lookup + 256, 0 );  // Using iota from <numeric>
lookup['\v'] = 'v';

for (int i = 0; i < s.size(); ++i)
{
    cout << "s[" << i << "]: " << lookup[s[i]] << endl;
    outfile << lookup[s[i]] << endl;
}

Now, this won't print the backslashes. To undo the string further check out std::iscntrl. It's locale-dependent, but you could utilise it. Or just something naive like:

const char *lookup[256] = { 0 };
s['\f'] = "\\f";
s['\n'] = "\\n";
s['\r'] = "\\r";
s['\t'] = "\\t";
s['\v'] = "\\v";
s['\"'] = "\\\"";
// Maybe add other controls such as 0x0E => "\\x0e" ...

for (int i = 0; i < s.size(); ++i)
{
    const char * x = lookup[s[i]];
    if( x ) {
        cout << "s[" << i << "]: " << x << endl;
        outfile << x << endl;
    } else {
        cout << "s[" << i << "]: " << s[i] << endl;
        outfile << s[i] << endl;
    }
}

Be aware there is no way to correctly reconstruct the escaped string as it originally appeared in code, because there are multiple ways to escape characters. Including ordinary characters.

Upvotes: 4

dreamcrash
dreamcrash

Reputation: 51393

Most likely the terminal that you are using cannot decipher the vertical space code "\v", thus printing something else. On my terminal it prints:

foo:bar-this-is-more_text@
                          enus  "some more text here to read."

To print the "\v" change or code to:

String s = "foo:bar-this-is-more_text@\\venus  \"some more text here to read.\"";

Upvotes: 4

user3437460
user3437460

Reputation: 17454

What am I missing? How can I have my program output just a backslash v?

You are escaping the letter v. To print backslash and v, escape the backslash. That is, print double backslash and a v.

\\v

Upvotes: 0

Related Questions