system() copy fails, while cmd copy works - c

In cmd.exe, I can execute the command "copy c:\hello.txt c:\hello2.txt" and it worked fine.
But in my C program, I ran this piece of code and got the following error:
#include <iostream>
using namespace std;
int main()
{
system("copy c:\hello.txt c:\hello2.txt");
system("pause");
return 0;
}
Output:
The system cannot find the file specified.
Anybody know what is going on here?

Inside C strings (and quite a few other languages that use the same escaping rules), \ should be \\ since it's the escape character. It allows you to enter, in normal text, non-printable characters such as:
the tab character \t.
the carriage-return character \r.
the newline character \n.
others which I won't cover in detail.
Since \ is used as the escape character, we need a way to put an actual '\' into a string. This is done with the sequence \\.
Your line should therefore be:
system("copy c:\\hello.txt c:\\hello2.txt");
This can sometimes lead to obscure errors with commands like:
FILE *fh = fopen ("c:\text.dat", "w");
where the \t is actually the tab character and the file that you're trying to open is:
c:TABext.dat.

Alternatively, all the Windows functions support Unix style slashes
system("copy c:/hello.txt c:/hello2.txt");
Some people prefer this since it's easier to spot an odd '\'.
But it might confuse Windows users if you display this path in a message.

Related

UTF-8 Japanese and Hangul script gets space inserted between characters in terminal emulator/tty

I have problems with printing Japanese and Hangul scripts encoded in UTF-8 in C. The program itself is trivial (I have omitted includes):
int main()
{
uint8_t valid_utf8_string1x[] = "宇宙に飛びたい"; //uint8_t is used on purpose
printf(valid_utf8_string1x);
return 0;
}
When I run it (on st, kitty or tty) every character is separated by regular space (code 32 dec), however copying it and pasting in (even in the same terminal window) or redirecting output to file (by ./program > outfile) will get rid of those, yet echo "宇宙に飛びたい" (where string is pasted without spaces) or cat outfile will make them appear again, even if they are not present in the input. Every other script I've tested (Greek, Russian, Polish and Latin, Arabic) worked fine. How can I get rid of spaces being printed? They mess up my UI.
PS. I copied and pasted the space itself between characters to get it's code.
It turns out it's an terminal feature.

Why can't I set printf's output format with dynamic args?

I want to control the printf() functions output format with dynamic parameter, just as the code showed below:
#include<stdio.h>
int main(int argc,char ** argv)
{
printf(argv[1],"hello,world");
return 0;
}
Then I compile and run it:
$ gcc -o test test.c
$ ./test "\t%s\n"
The result is strange:
\thello,world\n$
Why "\n" and "\t" has no effect?
Because the escapes you use (\t and \n) are interpreted inside string literals by the C compiler, not by printf(). This:
const char *newline1 = "\n", newline2[] = { '\n', 0 };
would generate the exact same content in newline1 and newline2, regardless of whether or not these are ever passed to printf(); the strings are there anyway.
Your code behaves just like this would:
printf("\\t%s\\n", "hello,world");
Here, I've double-escaped the special characters to generate a string with the same actual content as your command-line argument, i.e. "\t%s\n" (six characters rather than four).
The proper way to dynamically control printf() is to build the format string in code. If you want C-like escapes at runtime, you need to interpret them yourself in some way.
The sequence \n in a string or character literal in C/C++ is a single byte with the numeric value 10 (on an ASCII system). When output on a terminal (try putchar(10)!) it just sets the output position for the next character on the terminal to the beginning of the next line (on *nix; on MacOS, I think, you need an additional \r, or 13 for carriage return to have the output position at the beginning of the line).
Similarily, a \t is the notation for a single byte with the value 9, which makes most terminals advance their cursor to the next tabulator position.
What you need is to insert a single byte of these values in the command line. How that can be done depends on your shell; in bash you can keep the shell from interpreting special characters by pressing Ctrl-V beforehand. That outputs e.g. a tab, displayed by showing some empty space (instead of making the shell show possible string continuations or whatever tab does in bash). bash strings in single or double quotes can include newlines without further efforts -- simply press enter.
Here is a sample run in a cygwin terminal with bash. I pressed the indicated keys at the indicated positions; I finished the command as usual with [return] after the closing single quote on the second line.
pressed Ctrl-v,[TAB] here | pressed [return] there
v v
$ ./printf-arg.exe ' %s
> '
hello,world
The > in the second line was output by the shell after I pressed enter within the string delimited by single quotes. (Which inserts a newline in the string). It is an indication that the string being edited is continued on that line.
As an aside, it is probably unsafe to use command line arguments this way in potentially hostile environments. Carefully crafted strings could access memory which is not meant to be accessed and e.g. redirect return addresses, thus corrupting the program.
It's because the compiler handles the escape sequences like "\n" etc., and it does it in string or character literals only.
if you pass interpreted "\t%s\n" to command it will work. However it is tricky to construct such string in shell. The easiest way I know is:
./test $'\t%s\n'
See ANSI quoting in man bash for the $'magick'

C: strtok and newlines in Windows vs Linux

I'm working on a C school assignment that is intended to be done on Windows, however, I'm programming it on OS X. While the other students working on Windows don't have problems reading a file, I do.
The code provided by the tutors splits the contents of a file on \n using this code:
/* Read ADFGX information */
adfgx = read_from_file("adfgx.txt");
/* Define the alphabet */
alphabet = strtok(adfgx, "\n");
/* Define the code symbols */
symbols = strtok(NULL, "\n");
However, the file adfgx.txt (which is provided for the assignment) has Windows style newlines (\r\n): I checked it with a hex editor. So, compiling this with the Microsoft C compiler from Visual Studio and running it on Windows splits the file correctly on newlines (\r\n). Which I think is weird, because I can not find any documentation on this behavior. The other part: when I compile it on OS X using gcc, and I run it: the \r is still included in the tokenized string, because it obviously splits on \n. If I change the delimiters to the strtok call to "\r\n", it works for me.
Is this normal that this behaves differently on Windows and Unix? How should I handle this in real life situations (assuming I'm trying to write portable code for Windows and Unix in C that should handle file input that uses \r\n)?
If you open the file with fopen("adfgx.txt", "r") on Windows, the file gets opened in "text mode" and the \r char gets implicitly stripped from subsequent fread calls. If you had opened the file on Windows with fopen("adfgx.txt", "rb"), the file gets opened in "binary mode", and the \r char remains. To learn about the "rb" mode, and other mode strings, you can read about the different mode parameters that fopen on Windows takes here. And as you might imagine, fwrite on Windows will automatically insert a \r into the stream in front of the \n char (as long as the file was not opened in binary mode).
Unix and MacOS treat \r as any ordinary character. Hence, strok(NULL, "\n") won't strip off the '\r' char, because you are not splitting on that.
The easy cross-platform fix would be to invoke strtok as follows on all platforms:
/* Define the alphabet */
alphabet = strtok(adfgx, "\r\n");
And I think passing "\r\n" as the delimiter string will clear up most of your issues of reading text files on Windows and vice-versa. I don't think strtok will return an empty string in either case, but you might need to check for an empty string on each strtok call (and invoke it again to read the next line).

What exactly is \r in C language?

#include <stdio.h>
int main()
{
int countch=0;
int countwd=1;
printf("Enter your sentence in lowercase: ");
char ch='a';
while(ch!='\r')
{
ch=getche();
if(ch==' ')
countwd++;
else
countch++;
}
printf("\n Words =%d ",countwd);
printf("Characters = %d",countch-1);
getch();
}
This is the program where I came across \r. What exactly is its role here? I am beginner in C and I appreciate a clear explanation on this.
'\r' is the carriage return character. The main times it would be useful are:
When reading text in binary mode, or which may come from a foreign OS, you'll find (and probably want to discard) it due to CR/LF line-endings from Windows-format text files.
When writing to an interactive terminal on stdout or stderr, '\r' can be used to move the cursor back to the beginning of the line, to overwrite it with new contents. This makes a nice primitive progress indicator.
The example code in your post is definitely a wrong way to use '\r'. It assumes a carriage return will precede the newline character at the end of a line entered, which is non-portable and only true on Windows. Instead the code should look for '\n' (newline), and discard any carriage return it finds before the newline. Or, it could use text mode and have the C library handle the translation (but text mode is ugly and probably should not be used).
It's Carriage Return. Source: http://msdn.microsoft.com/en-us/library/6aw8xdf2(v=vs.80).aspx
The following repeats the loop until the user has pressed the Return key.
while(ch!='\r')
{
ch=getche();
}
Once upon a time, people had terminals like typewriters (with only upper-case letters, but that's another story). Search for 'Teletype', and how do you think tty got used for 'terminal device'?
Those devices had two separate motions. The carriage return moved the print head back to the start of the line without scrolling the paper; the line feed character moved the paper up a line without moving the print head back to the beginning of the line. So, on those devices, you needed two control characters to get the print head back to the start of the next line: a carriage return and a line feed. Because this was mechanical, it took time, so you had to pause for long enough before sending more characters to the terminal after sending the CR and LF characters. One use for CR without LF was to do 'bold' by overstriking the characters on the line. You'd write the line out once, then use CR to start over and print twice over the characters that needed to be bold. You could also, of course, type X's over stuff that you wanted partially hidden, or create very dense ASCII art pictures with judicious overstriking.
On Unix, all the logic for this stuff was hidden in a terminal driver. You could use the stty command and the underlying functions (in those days, ioctl() calls; they were sanitized into the termios interface by POSIX.1 in 1988) to tweak all sorts of ways that the terminal behaved.
Eventually, you got 'glass terminals' where the speeds were greater and and there were new idiosyncrasies to deal with - Hazeltine glitches and so on and so forth. These got enshrined in the termcap and later terminfo libraries, and then further encapsulated behind the curses library.
However, some other (non-Unix) systems did not hide things as well, and you had to deal with CRLF in your text files - and no, this is not just Windows and DOS that were in the 'CRLF' camp.
Anyway, on some systems, the C library has to deal with text files that contain CRLF line endings and presents those to you as if there were only a newline at the end of the line. However, if you choose to treat the text file as a binary file, you will see the CR characters as well as the LF.
Systems like the old Mac OS (version 9 or earlier) used just CR (aka \r) for the line ending. Systems like DOS and Windows (and, I believe, many of the DEC systems such as VMS and RSTS) used CRLF for the line ending. Many of the Internet standards (such as mail) mandate CRLF line endings. And Unix has always used just LF (aka NL or newline, hence \n) for its line endings. And most people, most of the time, manage to ignore CR.
Your code is rather funky in looking for \r. On a system compliant with the C standard, you won't see the CR unless the file is opened in binary mode; the CRLF or CR will be mapped to NL by the C runtime library.
There are a few characters which can indicate a new line. The usual ones are these two:
'\n' or '0x0A' (10 in decimal) -> This character is called "Line Feed" (LF).
'\r' or '0x0D' (13 in decimal) -> This one is called "Carriage return" (CR).
Different Operating Systems handle newlines in a different way. Here is a short list of the most common ones:
DOS and Windows
They expect a newline to be the combination of two characters, namely '\r\n' (or 13 followed by 10).
Unix (and hence Linux as well)
Unix uses a single '\n' to indicate a new line.
Mac
Macs use a single '\r'.
That is not always true; it only works in Windows.
For interacting with terminal in putty, Linux shell,... it will be used for returning the cursor to the beginning of line.
following picture shows the usage of that:
Without '\r':
Data comes without '\r' to the putty terminal, it has just '\n'.
it means that data will be printed just in next line.
With '\r':
Data comes with '\r', i.e. string ends with '\r\n'. So the cursor in putty terminal not only will go to the next line but also at the beginning of line
It depends upon which platform you're on as to how it will be translated and whether it will be there at all: Wikipedia entry on newline
\r is an escape sequence character or void character. It is used to bring the cursor to the beginning of the line (it maybe of same or new line) to overwrite with new content (content written ahead of \r like: \rhello);
int main ()
{
printf("Hello \rworld");
return 0;
}
The output of the program will be world not Hello world
because \r has put the cursor at the beginning of the line and Hello has been overwritten with world.

How to go to the previous line in a C code

If for the following code:
printf("HEllo\n"); // do not change this line.
printf("\b\bworld");
I need an output: Helloworld (In a single line). But this does not work fine. Could anyone please explain the reason? And other escape sequence if any.
There is no platform-independent control character to move back up a line. This harkens back to the days of line printers, where printf actually would print a line of text onto a sheet of paper and there was no way of retracting the paper to overwrite what had already been printed.
That said, there are libraries like ncurses that let you move the cursor around the console. They're just not part of the standard libraries.
How about simply:
printf("Helloworld");
\n is an escape sequence for a new line. Since you want everything to appear on the same line, there's no reason to specify \n.
The problem is you can't reliably move back up a line (using \b) after you've printed a new line. But if you require that there be two lines of code in your source, you can simply omit both escape sequences:
printf("HEllo");
printf("world");
If you're writing a Win32 console application, you can take advantage of the Console Screen Buffer API. The following code will move 1 line up:
printf("HEllo\n");
CONSOLE_SCREEN_BUFFER_INFO coninfo;
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsole, &coninfo);
coninfo.dwCursorPosition.Y -= 1; // move up one line
coninfo.dwCursorPosition.X += 5; // move to the right the length of the word
SetConsoleCursorPosition(hConsole, coninfo.dwCursorPosition);
printf("world");
Output:
HElloworld
Remove "\n" from your first printf. It moves the cursor to a new line.
Here is the list of escape sequences.
If you can't remove "\n", then you can do make a copy of a substring without these charaters. See the following example:
const char* from = "12345678";
char *to = (char*) malloc(6);
strncpy(to, from+2, 5);
All you need is to determine the index of "\n" characters.
The backspace character, when sent to a stream (such as through the printf() family of functions), does not seek backward in the file, it is sent as-is. If you run your example, the backspace character will be output as "garbage".
If you don't want a new line, don't post a newline character.
It is because '\b' is a terminal escape code... (sans the 'escape' of course ;-)
so it only modifies what you see on the terminal. That is, the terminal adjusts its display to respond to the backspace code, even though it received everything prior to it. A file also receives everything, including the backspace code, but it is not a tty device so the file's content is not modified; it keeps everything you send to it.
If printing an extra blank is a problem, then you should code some extra logic to print the trailing blank on every output except the last.
Reference This is in reference to files but maybe same idea applies. You might want to check out this link there is a very detailed explanation that most probably answers your question.
In a console, you can't go up a line. You can clear the screen and redraw it (which simulate going up a line.) Or you can rewrite on the same line. \r will take you to the beginning of the line you just printed.
You can do it actually in a platform-independent* way, assuming that you can somehow calculate the x offset of the previous line.
int x = printf("Hello, World!\n");
gotoxy(x-1-1,gety()-1); // One for the length-offset difference and the other to skip \n
printf("\b \b");
You can avoid using that variable by directly replacing it with x.
Note: printf() returns an int (the length of the passed String (of characters)). Use it wisely :)

Resources