I am writing a program that uses prints a hex dump of its input. However, I'm running into problems when newlines, tabs, etc are passed in and destroying my output formatting.
How can I use printf (or cout I guess) to print '\n' instead of printing an actual newline? Do I just need to do some manual parsing for this?
EDIT: I'm receiving my data dynamically, it's not just the \n that I'm corned about, but rather all symbols. For example, this is my printf statement:
printf("%c", theChar);
How can I make this print \n when a newline is passed in as theChar but still make it print normal text when theChar is a valid printable character?
Print "\\n" – "\\" produces "\" and then "n" is recognized as an ordinary symbol. For more information see here.
The function printchar() below will print some characters as "special", and print the octal code for characters out of range (a la Emacs), but print normal characters otherwise. I also took the liberty of having '\n' print a real '\n' after it to make your output more readable. Also note that I use an int in the loop in main just to be able to iterate over the whole range of unsigned char. In your usage you would likely just have an unsigned char that you read from your dataset.
#include <stdio.h>
static void printchar(unsigned char theChar) {
switch (theChar) {
case '\n':
printf("\\n\n");
break;
case '\r':
printf("\\r");
break;
case '\t':
printf("\\t");
break;
default:
if ((theChar < 0x20) || (theChar > 0x7f)) {
printf("\\%03o", (unsigned char)theChar);
} else {
printf("%c", theChar);
}
break;
}
}
int main(int argc, char** argv) {
int theChar;
(void)argc;
(void)argv;
for (theChar = 0x00; theChar <= 0xff; theChar++) {
printchar((unsigned char)theChar);
}
printf("\n");
}
Just use "\\n" (two slashes)
You can escape the backslash to make it print just a normal backslash: "\\n".
Edit: Yes you'll have to do some manual parsing. However the code to do so, would just be a search and replace.
If you want to make sure that you don't print any non-printable characters, then you can use the functions in ctype.h like isprint:
if( isprint( theChar ) )
printf( "%c", theChar )
else
switch( theChar )
{
case '\n':
printf( "\\n" );
break;
... repeat for other interesting control characters ...
default:
printf( "\\0%hho", theChar ); // print octal representation of character.
break;
}
printf("\\n");
In addition to the examples provided by other people, you should look at the character classification functions like isprint() and iscntrl(). Those can be used to detect which characters are or aren't printable without having to hardcode hex values from an ascii table.
In C/C++, the '\' character is reserved as the escape character. So whenever you want to actually print a '\', you must enter '\'. So to print the actual '\n' value you would print the following:
printf("\\n");
Just use String::replace to replace the offending characters before you call printf.
You could wrap the printf to do something like this:
void printfNeat(char* str)
{
string tidyString(str);
tidyString.replace("\n", "\\n");
printf(tidyString);
}
...and just add extra replace statements to rid yourself of other unwanted characters.
[Edit] or if you want to use arguments, try this:
void printfNeat(char* str, ...)
{
va_list argList;
va_start(argList, msg);
string tidyString(str);
tidyString.replace("\n", "\\n");
vprintf(tidyString, argList);
va_end(argList);
}
As of C++11 you can also use raw strings
std::printf(R"(\n)");
everything inside the R"( and )" will be printed literally. escape sequences will not be processed.
There are three solutions for this question:
Solution 1:
Every Symbol, Number, Alphabet has it's own ASCII value. The ASCII value of '\' as 92 and 'n' as 110. The immediate values(Numbers (ASCII)) are stored onto two integer variables. While printing, the format specifier %c (Character), is used.
void main() {
int i=92, j=110;
clrscr();
printf("%c%c", i, j);
getch();
}
Try it out in your C programming software...
Solution 2:
The programs works. But I think this one isn't fair...
At the output screen, type the input as \n...
you will get another \n..
void main() {
char a[10];
gets(a);
printf("\n\n\n\n");
puts(a);
getch();
}
Try out the programs
Solution 3:
Already said above use \n
Related
Assume that i put ' 123abc' as input in C++ console application.
if i get input as
int a; char ch;
scanf("%d", &a);
scanf("%ch", &ch);
i got 123 in a, 'a' in ch. Right?
Then, where does 4 blanks go? scanf just blow away blanks?
Is there no way can i get that blanks after i get 123abc?
To sum it up my question,
When i get int input with scanf, does scanf blow away blank in buffer?
What does happen i execute that code?
Can i get 4 blanks in ' 123abc' after i get '123' and 'a'?
As others pointed out, you really should read scanf documentation so you can see which specifier will be able to read whitespaces.
Regarding your first question:
When i get int input with scanf, does scanf blow away blank in buffer? What does happen i execute that code?
For numeric inputs, scanf will ignore any whitespace character.
When you execute scanf("%d", &a); it will go over the spaces (or any other whitespace character) until it finds a digit and start reading a decimal integer (as specified by %d).
Regarding your second question:
Can i get 4 blanks in ' 123abc' after i get '123' and 'a'?
I'm not sure what you mean here, you want to read a past value after having gone through the whole buffer?
You won't be able to do this.
If you need the spaces, get them before reading anything else.
Or read the whole buffer into your own buffer and deal with it.
There are many ways to deal with this.
Here's an example:
#include <cstdio>
int main()
{
{
printf( "Reading into your own buffer:\n" );
char my_buffer[128];
scanf( "%127[^\n]%*c", my_buffer ); // the %*c is to throw away the trailing \n
printf( "my_buffer: [%s]\n", my_buffer );
}
{
printf( "Reading each part separately:\n" );
char spaces[5];
int number;
char remaining_chars[4];
scanf( "%4[ ]", spaces );
scanf( "%d", &number );
scanf( "%3s", remaining_chars );
printf( " spaces: [%s]\n", spaces );
printf( " number: [%d]\n", number );
printf( "remaining_chars: [%s]\n", remaining_chars );
}
return 0;
}
And here is a sample run:
Reading into your own buffer:
123abc
my_buffer: [ 123abc]
Reading each part separately:
123abc
spaces: [ ]
number: [123]
remaining_chars: [abc]
I recommend you to read this documentation about scanf.
Whitespace character: the function will read and ignore any whitespace
characters encountered before the next non-whitespace character
(whitespace characters include spaces, newline and tab characters --
see isspace). A single whitespace in the format string validates any
quantity of whitespace characters extracted from the stream (including
none).
and if you wont to read sentence you can use fscanf or getline
EDIT This is how to do it -
scanf(" %[^\n]",str);
the anser is from this qustion here
I'm currently writing an assembler and VM program. My assembler reads in a .asm file and converts it to byte code that my VM then runs.
Currently I read in a line from my assembly file, break that line into it's components, and then determine what the line contains (is it a directive, or an instruction)
getline(assemblyFile, line);
istringstream iss(line);
vector<string> instruction{
std::istream_iterator<std::string>(iss),{}
};
This gives me a vector of strings that has been working well for me up to this point. If my directive is an int, I'm able to retrieve it simply by saying
mem[dataCounter] = stoi(instruction[VALUE]);
This was also working well when I was using ASCII values for my characters. However, I'm trying now to be able to provide either ASCII representation, or use a notation like
J .BYT 'J'
Where the first J is a label, the .BYT tells me what data type it is, and my 'J' is the byte I'm wanting to store in my byte array. If I don't use quotes,
J .BYT J
the following works nicely
mem[dataCounter] = int(instruction[VALUE].c_str()[0]);
(gives me the decimal/byte value), where instruction is whole line, and VALUE is an index of 2. If I use the former, it of course returns the first quote. Not using quotes may be the solution in and of itself, however, I'm also having trouble reading in special characters, such as spaces, or newline characters. In the case of spaces, my directive looks like
SPACE .BYT ' '
which returns me a vector that has four elements, "SPACE", ".BYT", "'" and "'", and in the case of my newline which I've been attempting as
NEWLN .BYT \n
I have three elements with the last being "\n".
In none of these cases have I been able to find yet a way to retrieve the characters I am attempting to represent in my .asm file to their equivalent char/decimal value. I would like to continue to use string as it's been convenient and changing would require a fair bit of refactoring, but can be done to support the functionality.
What methods/functions are available that can help me retrieve these characters, in particular the special characters?
I would use strtok() and treat special characters with caution.
For example, I would examine whether the token is a newline, and if it is explicitly state it.
For the ' ', I would search for it in the string, and if found, remember its information (starting position for example in the string) and then erase it from the string. Afterwards, I would split into tokens.
Minimal Example for demonstrative purposes only:
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
int main ()
{
//std::string str ="SPACE .BYT \n";
//std::string str = "J .BYT 'J'";
std::string str ="SPACE .BYT ' '";
std::size_t start_position_to_erase = str.find("' '");
if(start_position_to_erase != std::string::npos) {
std::cout << "Found: " << std::string(str, start_position_to_erase, start_position_to_erase+3) << std::endl;
str.erase(start_position_to_erase, 3);
}
char * pch;
printf ("Splitting string \"%s\" into tokens:\n", str.c_str());
pch = strtok ((char*)str.c_str()," ");
while (pch != NULL)
{
if(pch[0] == '\n')
printf ("\\n");
else
printf ("%s\n",pch);
pch = strtok (NULL, " ");
}
return 0;
}
Output:
Found: ' '
Splitting string "SPACE .BYT " into tokens:
SPACE
.BYT
I am making a program to translate English to Morse Code, using a series of conditional statements. I am using the following function:
void english (char text1){
if (text1=='a'||text1=='A'){cout<<".- ";}
else if (text1=='b'||text1=='B'){cout<<"-... ";}
.
.
.
else if (text1=='z'||text1=='Z'){cout<<"--.. ";}
else if (text1==' '){cout<<"/";}
}
There's one very simple problem. I cannot get my program to print anything for when there is a space character in the input; it should print a slash. I also tried else if (isspace(text1)) instead of else if (text1==' '), but with no luck.
The problem is not in the function you have posted code for. The problem is in the code which reads input. You may for example need to use std::getline(cin, line) to get an entire line with whitespace intact, or perhaps easier, get one character at a time:
for (char ch; cin.get(ch); ) {
english(ch);
}
bool stringMatch(const char *expr, const char *str) {
// do something to compare *(expr+i) == '\\'
// In this case it is comparing against a backslash
// i is some integer
}
int main() {
string a = "a\sb";
string b = "a b";
cout << stringMatch(a.c_str(), b.c_str()) << endl;
return 1;
}
So the problem right now is: Xcode is not reading in the '\', when I was debugging in stringMatch function, expr appears only to be 'asb' instead of the literal a\sb'.
And Xcode is spitting out an warning at the line:
string a = "a\sb" : Unknown escape sequence
Edit: I have already tried using "a\\sb", it reads in as "a\\sb" as literal.
bool stringMatch(const char *expr, const char *str) {
// do something to compare *(expr+i) == '\\'
// In this case it is comparing against a backslash
// i is some integer
}
int main() {
string a = "a\\sb";
string b = "a b";
cout << stringMatch(a.c_str(), b.c_str()) << endl;
return 1;
}
C and C++ deal with backslashes as escape sequences by default. You got to tell C to not use your backslash as an escape sequence by adding an extra backslash to your string.
These are the common escape sequences:
\a - Bell(beep)
\b - Backspace
\f - Formfeed
\n - New line
\r - Carriage Return
\t - Horizontal Tab
\\ - Backslash
\' - Single Quotation Mark
\" - Double Quatation Mark
\ooo - Octal Representation
\xdd - Hexadecimal Representaion
EDIT: Xcode is behaving abnormally on your machine. So I can suggest you this.
bool stringMatch(const char *expr, const char *str) {
// do something to compare *(expr+i) == '\\'
// In this case it is comparing against a backslash
// i is some integer
}
int main() {
string a = "a" "\x5C" "sb";
string b = "a b";
cout << stringMatch(a.c_str(), b.c_str()) << endl;
return 1;
}
Don't worry about the spaces in the string a declaration, Xcode concatenates strings separated with a space.
EDIT 2: Indeed Xcode is reading your "a\\b" literally, that's how it deals with escaped backslashes. When you'll output string a = "a\\sb" to console, you'll see, a\sb. But when you'll pass string a between methods as argument or as a private member then it will take the extra backslash literally. You have to design your code considering this fact so that it ignores the extra backslash. It's upto you how you handle the string.
EDIT 3: Edit 1 is your optimal answer here, but here's another one.
Add code in your stringMatch() method to replace double backslashes with single backslash.
You just need to add this extra line at the very start of the function:
expr=[expr stringByReplacingOccurrencesOfString:#"\\\\" withString:#"\\"];
This should solve the double backslash problem.
EDIT 4:
Some people think Edit 3 is ObjectiveC and thus is not optimal, so another option in ObjectiveC++.
void searchAndReplace(std::string& value, std::string const& search,std::string const& replace)
{
std::string::size_type next;
for(next = value.find(search); // Try and find the first match
next != std::string::npos; // next is npos if nothing was found
next = value.find(search,next) // search for the next match starting after
// the last match that was found.
)
{
// Inside the loop. So we found a match.
value.replace(next,search.length(),replace); // Do the replacement.
next += replace.length(); // Move to just after the replace
// This is the point were we start
// the next search from.
}
}
EDIT 5: If you change the const char * in stringMatch() to 'string` it will be less complex for you.
expr.replace(/*size_t*/ pos1, /*size_t*/ n1, /*const string&*/ str );
EDIT 6: From C++11 on, there exists something like raw string literals.
This means you don't have to escape, instead, you can write the following:
string a = R"raw(a\sb)raw";
Note that the raw in the string can be replaced by any delimiter of your choosing. This for the case you want to use a sub string like )raw in the actual string. Using these raw string literals mainly make sense when you have to escape characters a lot, like in combination with std::regex.
P.S. You have all the answers now, so it's upto you which one you implement that gives you the best results.
Xcode is spitting out that warning because it is interpreting \s in "a\sb" as an escape sequence, but \s is not a valid escape sequence. It gets replaced with just s so the string becomes "asb".
Escaping the backslash like "a\\sb" is the correct solution. If this somehow didn't work for you please post more details on that.
Here's an example.
#include <iostream>
#include <string>
int main() {
std::string a = "a\\sb";
std::cout << a.size() << ' ' << a << '\n';
}
The output of this program looks like:
If you get different output please post it. Also please post exactly what problem you observed when you tried "a\\sb" earlier.
Regexs can be a pain in C++ because backslashes have to be escaped this way. C++11 has raw strings that don't allow any kind of escaping so that escaping the backslash is unnecessary: R"(a\sb)".
How print format string passed as argument ?
example.cpp:
#include <iostream>
int main(int ac, char* av[])
{
printf(av[1],"anything");
return 0;
}
try:
example.exe "print this\non newline"
output is:
print this\non newline
instead I want:
print this
on newline
No, do not do that! That is a very severe vulnerability. You should never accept format strings as input. If you would like to print a newline whenever you see a "\n", a better approach would be:
#include <iostream>
#include <cstdlib>
int main(int argc, char* argv[])
{
if ( argc != 2 ){
std::cerr << "Exactly one parameter required!" << std::endl;
return 1;
}
int idx = 0;
const char* str = argv[1];
while ( str[idx] != '\0' ){
if ( (str[idx]=='\\') && (str[idx+1]=='n') ){
std::cout << std::endl;
idx+=2;
}else{
std::cout << str[idx];
idx++;
}
}
return 0;
}
Or, if you are including the Boost C++ Libraries in your project, you can use the boost::replace_all function to replace instances of "\\n" with "\n", as suggested by Pukku.
At least if I understand correctly, you question is really about converting the "\n" escape sequence into a new-line character. That happens at compile time, so if (for example) you enter the "\n" on the command line, it gets printed out as "\n" instead of being converted to a new-line character.
I wrote some code years ago to convert escape sequences when you want it done. Please don't pass it as the first argument to printf though. If you want to print a string entered by the user, use fputs, or the "%s" conversion format:
int main(int argc, char **argv) {
if (argc > 1)
printf("%s", translate(argv[1]));
return 0;
}
You can't do that because \n and the like are parsed by the C compiler. In the generated code, the actual numerical value is written.
What this means is that your input string will have to actually contain the character value 13 (or 10 or both) to be considered a new line because the C functions do not know how to handle these special characters since the C compiler does it for them.
Alternatively you can just replace every instance of \\n with \n in your string before sending it to printf.
passing user arguments directly to printf causes a exploit called "String format attack"
See Wikipedia and Much more details
There's no way to automatically have the string contain a newline. You'll have to do some kind of string replace on your own before you use the parameter.
It is only the compiler that converts \n etc to the actual ASCII character when it finds that sequence in a string.
If you want to do it for a string that you get from somewhere, you need to manipulate the string directly and replace the string "\n" with a CR/LF etc. etc.
If you do that, don't forget that "\\" becomes '\' too.
Please never ever use char* buffers in C++, there is a nice std::string class that's safer and more elegant.
I know the answer but is this thread is active ?
btw
you can try
example.exe "print this$(echo -e "\n ")on newline".
I tried and executed
Regards,
Shahid nx