entering newline character into a string - c++

In these two cases I am entering \n as user input (in a string) in one and I am making \n as a part of string in the program itself (no user input):
string str1;
cin>>str1; //case 1 - \n entered as the part of the input
string str="hello\n"; //case 2
in case 1 \n is considered as a part of the input string whereas in case 2 it is considered as newline - why?

Escape sequences are compiler-time only literals. When your compiler comes across a \ in a string, it looks for a pattern afterwards to determine the value.
When you read in from the console, the input is read one character at a time.
Most debuggers will show the inputted string as "hello\\n", or broken up into individual characters:
'h','e','l','l','o','\\','n'
When you manually set the string in the code, such as string str = "hello\n", the compiler recognizes the escape sequence and treats it as the single character '\n'. This allows programmers to have shorthand for printing characters without going and printing their ASCII values.
Users, on the other hand, have an enter button to conveniently add a newline, and programs are generally oriented to have a human-readable interface(i.e., if I type a '\' character I expect it to be a '\' if I have no experience with computers)
Another note about cin is that it uses newline characters other whitespace to distinguish between kinds of input. The function getline is meant for string input for getting around this, but the stream extraction is done from whitespace to whitespace so it is consistent with all data types(int,float,char,etc)

Related

c++: How to insert Line Feed into sprintf concatenation?

I am trying to send two commands at once with sprintf. Commands should be separated with 0x0A (LF). I thought I could enter special characters using two slashes, so I am writing:
sprintf(tmpstr,"VSET1:%ld.%3.3d\\x0AVSET2:%ld.%3.3d",mv/1000, AbsVal((int)mv%1000), mv / 1000, AbsVal((int)mv % 1000));
and it seems only the second command (VSET2) is recognized.
What am I doing wrong?
Use \n in the format string. Also, use a single backslash not \\.
If you are writing your buffer to a file, open the file in binary mode.
Whether you use \n or \x0A, you have to open the file in binary mode to avoid non-portable translations.
See Escape sequences.
When you use \\x0A in a string literal, the first backslash escapes the second backslash. As a result, the string contains a backslash character, '\\', followed by characters 'x', '0', and 'A'.
To use the character represented by 0x0A, you need to use \x0A.
You should be using a single backslash instead of two backslashes. Try the statement given below:
sprintf(tmpstr,"VSET1:%ld.%3.3d\x0AVSET2:%ld.%3.3d",mv/1000, AbsVal((int)mv%1000), mv / 1000, AbsVal((int)mv % 1000));
However, what you have done in your program will print a string "\x0A", rather than an ASCII character (0xAA (Line Feed)).
In C, all escape sequences consist of two or more characters, the first of which is the backslash, \ (called the "Escape character"); the remaining characters determine the interpretation of the escape sequence.
C deal with backslashes as escape sequences by default. However, in your program, you have told C compiler to not use your backslash as an escape sequence by adding an extra backslash to your string.
This works perfect. You not only get to insert \n but looks correct in the code. No need for a \ at the end of lines either. I use this for big paragraphs. Personal data has been obfuscated.
enter code here
wchar_t msg[200];
swprintf(msg, L"XYZ%d: ABCD Limit set to %d%%. %d times it has abcd and xyz rstu %d%%\n"
"Do you want to fix it?\n"
"An Yes will fix it\n"
"No will ignore it and continue\n"
"Cancel will abort the run\n", xxx, yyy, zzz, aaa);

Trim leading and trailing spaces after "=" symbols in string c++

I have a line which have data coming with "=" symbols. i need to ignore all white spaces before and after "=" symbol in my string
example:
input i have: "this is test = test1 and test1= test2"
output I am looking for:
"this is test=test1 and test1=test2"
I have tried with istream ignore function and std::find function for string but not sure how can i remove trailing spaces unless a non-whites pace character occurs in the string.
I found a similar question here but it is not answered.
:
https://stackoverflow.com/questions/24265598/delimiter-is-getting-added-at-the-beginning-of-each-line-of-a-delimited-file-whi
Thanks
Ruchi
If the other whitespace may be replaced by a single space, then you can read in all words from the string (std::cin <<), write them in a new string separated by a space and handle the needed tokens like "=" in this case by putting it in the string without spaces. You will probably need some "spaceNeeded" flags to handle no space before and after the token.

Include )" in raw string literal without terminating said literal

The two characters )" terminate the raw string literal in the example below.
The sequence )" could appear in my text at some point, and I want the string to continue even if this sequence is found within it.
R"(
Some Text)"
)"; // ^^
How can I include the sequence )" within the string literal without terminating it?
Raw string literals let you specify an almost arbitrary* delimiter:
//choose ### as the delimiter so only )###" ends the string
R"###(
Some Text)"
)###";
*The exact rules are: "any member of the basic source character set except:
space, the left parenthesis (, the right parenthesis ), the backslash \,
and the control characters representing horizontal tab,
vertical tab, form feed, and newline" (N3936 §2.14.5 [lex.string] grammar) and "at most 16 characters" (§2.14.5/2)
Escaping won't help you since this is a raw literal, but the syntax is designed to allow clear demarcation of start and end, by introducing a little arbitrary phrase like aha.
R"aha(
Some Text)"
)aha";
By the way note the order of ) and " at the end, opposite of your example.
Regarding the formal, at first sight (studying the standard) it might seem as if escaping works the same in raw string literals as in ordinary literals. Except one knows that it doesn't, so how is that possible, when no exception is noted in the rules? Well, when raw string literals were introduced in C++11 it was by way of introducing an extra undoing translation phase, undoing the effect of e.g. escaping!, to wit, …
C++11 §2.5/3
” Between the
initial and final double quote characters of the raw string, any transformations performed in phases 1
and 2 (trigraphs, universal-character-names, and line splicing) are reverted; this reversion shall apply
before any d-char, r-char, or delimiting parenthesis is identified.
This takes care of Unicode character specifications (the universal-character-names like \u0042), which although they look and act like escapes are formally, in C++, not escape sequences.
The true formal escapes are handled, or rather, not handled!, by using a custom grammar rule for the content of a raw string literal. Namely that in C++ §2.14.5 the raw-string grammar entity is defined as
" d-char-sequenceopt ( r-char-sequenceopt ) d-char-sequenceopt "
where an r-char-sequence is defined as a sequence of r-char, each of which is
” any member of the source character set, except
a right parenthesis ) followed by the initial d-char-sequence
[like aha above] (which may be empty) followed by a double quote "
Essentially the above means that not only can you not use escapes directly in raw strings (which is much of the point, it's positive, not negative), you can't use Unicode character specifications directly either.
Here's how to do it indirectly:
#include <iostream>
using namespace std;
auto main() -> int
{
cout << "Ordinary string with a '\u0042' character.\n";
cout << R"(Raw string without a '\u0042' character, and no \n either.)" "\n";
cout << R"(Raw string without a '\u0042' character, i.e. no ')" "\u0042" R"(' character.)" "\n";
}
Output:
Ordinary string with a 'B' character.
Raw string without a '\u0042' character, and no \n either.
Raw string without a '\u0042' character, i.e. no 'B' character.
You can use,
R"aaa(
Some Text)"
)aaa";
Here aaa will be your string delimiter.

String replacement and strange characters

I have an HTML data in a char* and I would like to get it line by line, do some replacements and then add them all up together into a single string. This is the code that I use
std::string to, finalData;
finalData = "";
char* char_array = strtok(data, "\n");
while(char_array){
finalData += std::string(char_array);
char_array = strtok(NULL, "\n");
}
The problem is the data that I get at the end of this (finalData) has a lot of ^M characters and I am unable to search for it as it has a special character. Is there any way to completely eliminate the character?
I am guessing that it has something to do with conversion from c array to c++ string and to do with \n as tab is represented by ^I and cntrl is represented as ^
It seems that you are on a Windows system, or that the data originated on a Windows system. On a Windows system, newline is actually two characters: "\r\n". What you are seeing as ^M is the carriage-return character ('\r') of that newline sequence.
One way to remove those extra characters, would be to use std::string::find and std::string::erase in a loop.
Another way would be to manually copy, character by character, to a new std::string, except if the character is '\r'.

Why doesn't my Regular Expression for an empty string work?

I've tested this on Regexr and it works, but it doesn't seem to work in AS3:
var emptyResult:* = new RegExp("^\s*$", "gi").exec(myField.text);
or
var emptyResult:* = /^\s*$/gi.exec(myField.text);
No matter whether I have text in the field or not, whitespace or non-whitespace, emptyResult is always null. I've tried with and without the g and i tags, but nothing seems to work.
Anyone know why this might be?
You don't need the 'i' flag - it stands for 'ignore case', which is only applicable to letters of Latin alphabet - you aren't using them.
In the first example, you need to escape the backslash, otherwise it's treated as if it was meant to escape the following letter 's'.
You don't need the 'g' flag either, since you are trying to test the entire string (in your case the line and the string are the same thing, \s will first encounter the end of the line, before $ can).
When using your second regexp, however, with the 'i' flag removed, it gives me the results I'd expect, i.e. if the entire text of the tested string consists of white space, tabulation, carriage return or line feed, then that entire string is returned.
For instance:
trace(/^\s*$/.exec(" \t\r\n")[0].length); // 4