Copy string to clipboard in c - c

First of all, I know there is a question with an identical name, however it deals with c++ and not c.
Is there any way to set a string to the clipboard in c?
This is the mentioned question if anyone is curious, even though it is for windows.
I need it to be in c because I am writing a program in c, and I would like to copy a string to the clipboard.
printf("Welcome! Please enter a sentence to begin.\n> ");
fgets(sentence, ARR_MAX, stdin);
//scan in sentence
int i;
char command[ARR_MAX + 25] = {0};
strncat(command, "echo '",6);
strncat(command, sentence, strlen(sentence));
strncat(command, "' | pbcopy",11);
command[ARR_MAX + 24] = '\0';
i = system(command); // Executes echo 'string' | pbcopy
The above code is saving 2 new lines in addition to the string. ARR_MAX is 300.

you tagged your question for osx. so this should be sufficient:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/PasteboardGuide106/Articles/pbCopying.html#//apple_ref/doc/uid/TP40008102-SW1
however there is the problem of having to call non-native c. Whether this is directly possible I don`t know.
if you can accept some hacky behavior you could invoke the pbcopy command.
http://osxdaily.com/2007/03/05/manipulating-the-clipboard-from-the-command-line/
this would be very easy to implement. here is a short function which should copy to clipboard. But I dont have osx handy so cannot test myself
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int copytoclipboard(const char *str) {
const char proto_cmd[] = "echo '%s' | pbcopy";
char cmd[strlen(str) + strlen(proto_cmd) - 1]; // -2 to remove the length of %s in proto cmd and + 1 for null terminator = -1
sprintf(cmd ,proto_cmd, str);
return system(cmd);
}
int main()
{
copytoclipboard("copy this to clipboard");
exit(0);
}

Related

Why can't my editor understand characters like é, è, à [duplicate]

My setup: gcc-4.9.2, UTF-8 environment.
The following C-program works in ASCII, but does not in UTF-8.
Create input file:
echo -n 'привет мир' > /tmp/вход
This is test.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 10
int main(void)
{
char buf[SIZE+1];
char *pat = "привет мир";
char str[SIZE+2];
FILE *f1;
FILE *f2;
f1 = fopen("/tmp/вход","r");
f2 = fopen("/tmp/выход","w");
if (fread(buf, 1, SIZE, f1) > 0) {
buf[SIZE] = 0;
if (strncmp(buf, pat, SIZE) == 0) {
sprintf(str, "% 11s\n", buf);
fwrite(str, 1, SIZE+2, f2);
}
}
fclose(f1);
fclose(f2);
exit(0);
}
Check the result:
./test; grep -q ' привет мир' /tmp/выход && echo OK
What should be done to make UTF-8 code work as if it was ASCII code - not to bother how many bytes a symbol takes, etc. In other words: what to change in the example to treat any UTF-8 symbol as a single unit (that includes argv, STDIN, STDOUT, STDERR, file input, output and the program code)?
#define SIZE 10
The buffer size of 10 is insufficient to store the UTF-8 string привет мир. Try changing it to a larger value. On my system (Ubuntu 12.04, gcc 4.8.1), changing it to 20, worked perfectly.
UTF-8 is a multibyte encoding which uses between 1 and 4 bytes per character. So, it is safer to use 40 as the buffer size above.
There is a big discussion at How many bytes does one Unicode character take? which might be interesting.
Siddhartha Ghosh's answer gives you the basic problem. Fixing your code requires more work, though.
I used the following script (chk-utf8-test.sh):
echo -n 'привет мир' > вход
make utf8-test
./utf8-test
grep -q 'привет мир' выход && echo OK
I called your program utf8-test.c and amended the source like this, removing the references to /tmp, and being more careful with lengths:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 40
int main(void)
{
char buf[SIZE + 1];
char *pat = "привет мир";
char str[SIZE + 2];
FILE *f1 = fopen("вход", "r");
FILE *f2 = fopen("выход", "w");
if (f1 == 0 || f2 == 0)
{
fprintf(stderr, "Failed to open one or both files\n");
return(1);
}
size_t nbytes;
if ((nbytes = fread(buf, 1, SIZE, f1)) > 0)
{
buf[nbytes] = 0;
if (strncmp(buf, pat, nbytes) == 0)
{
sprintf(str, "%.*s\n", (int)nbytes, buf);
fwrite(str, 1, nbytes, f2);
}
}
fclose(f1);
fclose(f2);
return(0);
}
And when I ran the script, I got:
$ bash -x chk-utf8-test.sh
+ '[' -f /etc/bashrc ']'
+ . /etc/bashrc
++ '[' -z '' ']'
++ return
+ alias 'r=fc -e -'
+ echo -n 'привет мир'
+ make utf8-test
gcc -O3 -g -std=c11 -Wall -Wextra -Werror utf8-test.c -o utf8-test
+ ./utf8-test
+ grep -q 'привет мир' $'в?\213?\205од'
+ echo OK
OK
$
For the record, I was using GCC 5.1.0 on Mac OS X 10.10.3.
This is more of a corollary to the other answers, but I'll try to explain this from a slightly different angle.
Here is Jonathan Leffler's version of your code, with three slight changes: (1) I made explicit the actual individual bytes in the UTF-8 strings; and (2) I modified the sprintf formatting string width specifier to hopefully do what you are actually attempting to do. Also tangentially (3) I used perror to get a slightly more useful error message when something fails.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 40
int main(void)
{
char buf[SIZE + 1];
char *pat = "\320\277\321\200\320\270\320\262\320\265\321\202"
" \320\274\320\270\321\200"; /* "привет мир" */
char str[SIZE + 2];
FILE *f1 = fopen("\320\262\321\205\320\276\320\264", "r"); /* "вход" */
FILE *f2 = fopen("\320\262\321\213\321\205\320\276\320\264", "w"); /* "выход" */
if (f1 == 0 || f2 == 0)
{
perror("Failed to open one or both files"); /* use perror() */
return(1);
}
size_t nbytes;
if ((nbytes = fread(buf, 1, SIZE, f1)) > 0)
{
buf[nbytes] = 0;
if (strncmp(buf, pat, nbytes) == 0)
{
sprintf(str, "%*s\n", 1+(int)nbytes, buf); /* nbytes+1 length specifier */
fwrite(str, 1, 1+nbytes, f2); /* +1 here too */
}
}
fclose(f1);
fclose(f2);
return(0);
}
The behavior of sprintf with a positive numeric width specifier is to pad with spaces from the left, so the space you tried to use is superfluous. But you have to make sure the target field is wider than the string you are printing in order for any padding to actually take place.
Just to make this answer self-contained, I will repeat what others have already said. A traditional char is always exactly one byte, but one character in UTF-8 is usually not exactly one byte, except when all your characters are actually ASCII. One of the attractions of UTF-8 is that legacy C code doesn't need to know anything about UTF-8 in order to continue to work, but of course, the assumption that one char is one glyph cannot hold. (As you can see, for example, the glyph п in "привет мир" maps to the two bytes -- and hence, two chars -- "\320\277".)
This is clearly less than ideal, but demonstrates that you can treat UTF-8 as "just bytes" if your code doesn't particularly care about glyph semantics. If yours does, you are better off switching to wchar_t as outlined e.g. here: http://www.gnu.org/software/libc/manual/html_node/Extended-Char-Intro.html
However, the standard wchar_t is less than ideal when the standard expectation is UTF-8. See e.g. the GNU libunistring documentation for a less intrusive alternative, and a bit of background. With that, you should be able to replace char with uint8_t and the various str* functions with u8_str* replacements and be done. The assumption that one glyph equals one byte will still need to be addressed, but that becomes a minor technicality in your example program. An adaptation is available at http://ideone.com/p0VfXq (though unfortunately the library is not available on http://ideone.com/ so it cannot be demonstrated there).
The following code works as required:
#include <stdio.h>
#include <locale.h>
#include <stdlib.h>
#include <wchar.h>
#define SIZE 10
int main(void)
{
setlocale(LC_ALL, "");
wchar_t buf[SIZE+1];
wchar_t *pat = L"привет мир";
wchar_t str[SIZE+2];
FILE *f1;
FILE *f2;
f1 = fopen("/tmp/вход","r");
f2 = fopen("/tmp/выход","w");
fgetws(buf, SIZE+1, f1);
if (wcsncmp(buf, pat, SIZE) == 0) {
swprintf(str, SIZE+2, L"% 11ls", buf);
fputws(str, f2);
}
fclose(f1);
fclose(f2);
exit(0);
}
Probably your test.c file is not stored in UTF-8 format and for that reason "привет мир" string is ASCII - and the comparison failed. Change text encoding of source file and try again.

reading from an input line with ""

I have this program that is supposed to read a line e.g post "nice job" john and i want to get every token in that line but for some reason i only get some of them.
Expected output:
post
nice job
john
My output:
post
nice
im sure im putting the correct format on sscanf so whats the problem i dont get why it doenst consider "nice job" as one word.
Program:
#include <stdio.h>
int main()
{
char token1[128];
char token2[128];
char token3[128];
char str[] = "post \"nice job\" john";
sscanf(str,"%s \"%s\" %s",token1,token2,token3);
puts(token1);
puts(token2);
puts(token3);
return(0);
}
The second %s reads "nice" because %s stops at the first whitespace. The format string then demands a match for a " quote, which isn't next (a space is next). The scanf functions don't skip input until a match is found, they stall. Always check the return value which should have been 3.
This code
#include <stdio.h>
int main()
{
char token1[128] = "";
char token2[128] = "";
char token3[128] = "";
char str[] = "post \"nice job\" john";
int res = sscanf(str, "%s \"%[^\"]\"%s", token1, token2, token3);
printf("%d\n", res);
puts(token1);
puts(token2);
puts(token3);
return(0);
}
outputs
3
post
nice job
john

Multiple (randomly chosen) outputs across different launches of the same program. Random characters added when fscanf'ing

Simple program: reads a name and a surname (John Smith) from a .txt file via fscanf, adds spaces, prints the name in the console (just as it's written in the .txt).
If compiled and ran on Win10 via
Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26433 for x86
the following code does not produce the same output for the same input across different .exe launches (no recompiling). For each input it seems to have multiple outputs avaialble, between which the program decides at random.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char input_file_name[255];
FILE * input_file;
char name[255];
input_file = fopen ("a.txt","r");
do
{
if (strlen(name) != 0 )
name[strlen(name)] = ' ';
fscanf (input_file, "%s", name + strlen(name) * sizeof(char));
}while(!feof(input_file));
fclose (input_file);
printf("Name:%s\n", name);
system("pause");
return 0;
}
I will list a couple of inputs and outputs for them. As not all characters are printable, I will type type them as \ascii_code instead, such as \97 = a.
The most common anomalies are \31 (Unit Separator) added at the very front of the string and \12 (NP form feed, new page) or \17 (device control 1) right before the surname (after the first space).
For "John Smith":
"John Smith" (proper output)
"\31 John Smith"
For "Atoroco Coco"
"Atoroco \12Coco"
"\31 Atoroco \16Coco"
For "Mickey Mouse"
"Mickey Mouse" (proper)
"\31 Mickey\81Mouse" (There is a \32 (space) in the string right before the \81, but the console doesn't show the space?!)
If compiled a different machine (MacOS, compiler unknown) it seems to work properly each time, that is it prints simply the .txt's contents.
Why are there multiple outputs produced, seemingly at random?
Why are these characters (\31, \12 etc) in particular added, and no other?
Your code invokes Undefined Behavior (UB), since it uses name uninitialized. Read more in What is Undefined Behaviour in C?
We will initialize it, and make sure the null terminator is there. Standard string functions, like strlen(), depend on the null terminator to mark the end of the string.
Then, you need to make sure that you read something before you call feof(). Moreover, it's a good idea to check what fscanf() returns, which denotes the number of items read.
Putting all together, we get:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char input_file_name[255];
FILE * input_file;
char name[255] = "\0"; // initialize it so that is has a null terminator
input_file = fopen ("a.txt","r");
do
{
if (strlen(name) != 0 )
name[strlen(name)] = ' ';
} while (fscanf (input_file, "%s ", name + strlen(name) * sizeof(char)) == 1 && !feof(input_file));
fclose (input_file);
printf("Name:%s\n", name);
return 0;
}
Output (for "georgios samaras"):
georgios samaras

built in command to change prompt in custom linux/unix shell

I have looked all over google and I find how to change in the bash config files, but my project requires a built in command to change the prompt.
I declared char pointer outside any function, my command modifies it, but when the function returns (int to continue a do while loop) and the prompt is displayed again, it is blank.
I have tried using a structure, union, and even a second char pointer and got the same issue.
I thought using a global char pointer that could be accessed and modified in any function would be the solution to this part of my project.
I would appreciate and will try any response.
Edit:
posted on my phone, tried to ask w/o code, but here it is
Code:
char *prmpt;
...
int main(int argc, char **argv)
prmpt="$$ ";
do
{
printf("%s ", prmpt);
}while(1)
int cmd_prompt(char **args)
{
prmpt = (char*)args[1];
return 1;
}
Essentially one needs to use fgets or getline or better yet they might use readline or editline. Here is an example using getline:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *prompt;
size_t len = 256;
size_t i = 0;
if (!(prompt = malloc(256 * sizeof(char))))
return 1;
strcpy(prompt, "$");
while ( 1 )
{
printf("[[%s]] ", prompt);
i = getline(&prompt, &len, stdin);
prompt[i-1] = '\0';
}
}
Or if you might try implementing getline on your own using getchar ( perhaps if getline is not available on your system, or you just want to know how it works). And eventually move on to writing your own editline library if you continue to be interested in writing shells.

Basic script in C (String display)

I'm trying to create a simple script on my server, basically I would like to sent a string and display it via system function...
#include <stdio.h>
int main()
{
char txt[100];
printf("Insert a text: ");
fgets(txt, 100, stdin);
system("echo %s"), txt;
return 0;
}
Rght now I'm not getting any string just "%s"
any idea why?
system("echo %s"), txt;
This isn't doing what you think; it's an expression which evaluates to txt. Since evaluating txt has no side effects, and since you're not capturing the result of the expression anywhere, adding , txt after the system call essentially does nothing. See this question for some information on the "comma"-operator in C.
Moreover, system doesn't support the use of printf-style format specifiers, so the %s in your string literal doesn't have any special meaning; it's just going to be echoed exactly as written, as you've seen. If you want to construct a command at runtime for use with system, you will have to do so with sprintf or similar.
The prototype to system() is:
int system(const char * command);
From man 3 system:
executes the shell command specified in command
From this we can safely assume s refers to a C-"string".
So prepare the string using for example snprintf():
char s[1024];
snprintf(s, 1024 -1, "echo %s", txt); /* -1 for the C-"string"'s 0-terminator */
Then pass it:
system(s);
Instead of system("echo %s"), txt; try this:
printf("%s", txt);
the system statement will not format the output, like printf.
suggest using:
#include <stdio.h>
#include <stdlib.h> // system()
#include <string.h> // strcpy(), strcat()
#define BUF_LEN (100)
int main()
{
char output[10+BUF_LEN] = "echo ";
char txt[BUF_LEN] = {'\0'};
printf("Insert a text: ");
fgets(txt, BUF_LEN, stdin);
strcat( output, txt );
system( output );
return 0;
}
The above code works very nicely, however;
do not include any command separators, semicolons, or other characters that would be interpreted by the shell in the input string.

Resources