Here is what I get when I try to encrypt "This is a test sentence!": "Ymnxp���p�����t�������"
I have tested my encryption part before and it worked fine.
Can anyone please tell me what did I do wrong here?
#include <iostream>
#include <string>
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
#include "unistd.h"
using namespace std;
void displayUsage(){
// Displays how to use this program
// TODO
cout << "Instruction: \n use -r to give rotation number \n use -f to give file name" <<endl;
}
int main(int argc, char **argv){
string text;
char* input_file_name;
int rotation;
bool have_rotation = false;
bool have_input_file_name = false;
// process command-line arguement
int opt = 0;
extern char *optarg;
static const char* opt_string = "r:f:";
opt = getopt( argc, argv, opt_string);
while(opt != -1) // While there are parameters to parse, do so
{
switch(opt)
{
case 'r':
have_rotation = true;
rotation = atoi(optarg);
break;
case 'f':
have_input_file_name = true;
input_file_name = optarg;
break;
default:
displayUsage();
return 1;
}
opt = getopt( argc, argv, opt_string); // Pull the next parameter, or 0 if none.
}
if(!have_rotation)
{
displayUsage();
return 0;
}
if(have_rotation)
{
if(have_input_file_name)
{
ifstream file(input_file_name);
string text2, temp;
while(!file.eof())
{
getline(file, temp);
text2 += temp;
text2 += "\n";
}
text = text2[text2.size()-2];
}
else
{
cout <<"Enter text:"<<endl;
cin >> text;
}
}
char cipher[text.size()];
for(int i=0; i<text.size(); i++)
{
cipher[i] = text[i];
if(islower(cipher[i]))
{
cipher[i] = (cipher[i] - 'a' + rotation)%26 + 'a';
}
else if(isupper(cipher[i]))
{
cipher[i] = (cipher[i] - 'A' + rotation)%26 + 'A';
}
}
cout <<cipher<<endl;
return 0;
}
I guess the error is because you did not terminate your cipher array with a '\0'.
The printing function will process characters from an array (and possibly beyond) until it finds a '\0' character.
Your array should be one bigger to account for this terminating character.
Or get rid of the char array and use std::string.
I can get my code run if I type the sentence manually. It doesn't printout anything if I input a text file.
#include <iostream>
#include <string>
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
#include "unistd.h"
using namespace std;
void displayUsage(){
// Displays how to use this program
// TODO
cout << "Instruction: \n use -r to give rotation number \n use -f to give file name" <<endl;
}
char caesar(char c, int r)
{
if(isalpha(c))
{
if(islower(c))
{
c = (((c-97)+r)%26)+97; // 97 is a value of 'a'
}
else if(isupper(c))
{
c = (((c-65)+r)%26)+65; // 65 is a value of 'A'
}
}
return c;
}
int main(int argc, char **argv){
string text;
char* input_file_name;
int rotation;
bool have_rotation = false;
bool have_input_file_name = false;
// process command-line arguement
int opt = 0;
extern char *optarg;
static const char* opt_string = "r:f:";
opt = getopt( argc, argv, opt_string);
while(opt != -1) // While there are parameters to parse, do so
{
switch(opt)
{
case 'r':
have_rotation = true;
rotation = atoi(optarg);
break;
case 'f':
have_input_file_name = true;
input_file_name = optarg;
break;
default:
displayUsage();
return 1;
}
opt = getopt( argc, argv, opt_string); // Pull the next parameter, or 0 if none.
}
if(!have_rotation)
{
displayUsage();
return 0;
}
if(have_rotation)
{
if(have_input_file_name)
{
ifstream file(input_file_name);
string text2, temp;
while(!file.eof())
{
getline(file, temp);
text2 += temp + "\n";
}
text = text2[text2.size()-2];
}
else
{
cout <<"Enter text:"<<endl;
getline(cin, text);
}
}
string output = "";
for(int i = 0; i < text.size(); i++)
{
output += caesar(text[i],rotation);
}
cout<<output<<endl;
return 0;
}
Related
what I expect: it will store the last ten commands entered in the terminal. And you can see them when you press ctrl+c. If you want to exit, just press ctrl+d.
So I implemented with queue to store commands. But after 'length = read(STDIN_FILENO, inputBuffer, MAX_LINE);', all the elements in queue are the newest command.(e.g. COMMAND->date queue:date; COMMAND->cal queue:cal cal)
It was normal before the 'read'. But it doesn't help when I replaced it with 'fgets(inputBuffer,MAX_LINE,stdin);'.And in this way, I don't know how to catch 'ctrl+d' because there is no signal corresponding to it(like SIGINT and ctrl+c) so I had to check if the length equals to 0.
how to solve this problem?
#include <signal.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <sys/wait.h>
#include <queue>
using namespace std;
#define BUFFER_SIZE 50
#define MAX_LINE 80 /* 80 chars per line, per command, should be enough. */
struct mes{
char* _args[MAX_LINE/2+1];
int len;
int bg;
int erno;
mes(){
len = 0;
bg = false;
memset(_args,0,sizeof(_args));
}
mes(char* new_args[],int _len,int _bg){
len = _len;
bg = _bg;
for(int i = 0; i < len; ++i){
_args[i] = new_args[i];
}
_args[len] = NULL;
}
void show(){
if(erno==-1) cout<<"ERROR:";
for(int i=0;i<len;i++)
cout<<_args[i]<<" ";
if(bg) cout<<"&"<<endl;
else cout<<endl;
}
~mes(){
memset(_args,0,sizeof(_args));
// for(int i=0; i<len && args[i]; i++){
// delete args[i];
// args[i]=NULL;
// }
// delete[] args;
// args=NULL;
}
};
queue <mes*> rec, quetmp;
static int reclen = 0;
static int totlen = 0;
void readSplit(char inputBuffer[], char *args[], int * background){
int length, /* # of characters in the command line */
i, /* loop index for accessing inputBuffer array */
start, /* index where beginning of next command parameter is */
ct; /* index of where to place the next parameter into args[] */
ct = 0;
if(!rec.empty()){
cout<<"before read"<<endl;
cout<<rec.front()->_args[0]<<endl;
cout<<"size:"<<sizeof(rec.front()->_args[0])<<'\n';
for(int k = 0; k < sizeof(rec.front()->_args[0]); ++k)
cout<<'*'<<rec.front()->_args[0][k]<<endl;
cout<<"end"<<endl;
}
/* read what the user enters on the command line */
// char *tmp = fgets(inputBuffer,MAX_LINE,stdin);
length = read(STDIN_FILENO, inputBuffer, MAX_LINE);
if(!rec.empty()){
cout<<"after read"<<endl;
cout<<rec.front()->_args[0]<<'\n';
cout<<"size:"<<sizeof(rec.front()->_args[0])<<'\n';
for(int k = 0; k < sizeof(rec.front()->_args[0]); ++k)
cout<<'*'<<rec.front()->_args[0][k]<<endl;
cout<<"end"<<endl;
}
start = -1;
if (length == 0){
write(STDOUT_FILENO,inputBuffer,strlen(inputBuffer));//write the last instruction
exit(0); /* ^d was entered, end of user command stream */
}
if (length < 0){
perror("error reading the command");
exit(-1); /* terminate with error code of -1 */
}
/* examine every character in the inputBuffer */
for (i=0;i<length;i++) {
switch (inputBuffer[i]){
case ' ':
case '\t' : /* argument separators */
if(start != -1){
args[ct] = &inputBuffer[start]; /* set up pointer */
ct++;
}
inputBuffer[i] = '\0'; /* add a null char; make a C string */
start = -1;
break;
case '\n': /* should be the final char examined */
if (start != -1){
args[ct] = &inputBuffer[start];
ct++;
}
inputBuffer[i] = '\0';
args[ct] = NULL; /* no more arguments to this command */
break;
default : /* some other character */
if (start == -1)
start = i;
if (inputBuffer[i] == '&'){
*background = 1;
inputBuffer[i] = '\0';
}
}
}
args[ct] = NULL; /* just in case the input line was > 80 */
// mes* pmes = new mes(args, ct, *background);
}
/**
* setup() reads in the next command line, separating it into distinct tokens
* using whitespace as delimiters. setup() sets the args parameter as a
* null-terminated string.
*/
//args end with NULL
//only deal with splitted command
void setup(char inputBuffer[], char *args[],int *background)
{
readSplit(inputBuffer, args, background);
int len = 0;
while(args[len]) ++len;
mes* pmes = new mes(args, len, *background);
int * p_errno=(int*)mmap(NULL,sizeof(int)*2,PROT_READ|PROT_WRITE,\
MAP_SHARED|MAP_ANONYMOUS,-1,0);
int * p_errno;
int pid = fork();
if(pid == 0){
int erno = execvp(args[0], args);
*p_errno = erno;
_exit(0);
}
else{
if(!(*background)){
waitpid(pid, NULL, 0);
}
// }
pmes->erno = 1;
pmes->erno = *p_errno;
if(reclen < 10){
rec.push(pmes);
++reclen;
}
else{
rec.pop();
rec.push(pmes);
}
++totlen;
}
void handle_SIGINT(int sig){// ctrl+c
int num = totlen - reclen, index = 0;
mes* ls[10];
cout<<endl;
while(!rec.empty()){
cout<<++num<<": ";
rec.front()->show();
quetmp.push(rec.front());
ls[index++] = rec.front();
rec.pop();
}
while(!quetmp.empty()){
rec.push(quetmp.front());
quetmp.pop();
}
cout<<"Exit record input \"q\", repeat command,\
input \"r\" or \"r x\"(x is the prefix of command)"<<endl;
char buffer[MAX_LINE];
char *arguments[MAX_LINE/2+1];
int flag;
int exeNum = index - 1;
while(true){
readSplit(buffer, arguments, &flag);
int num_arg = 0;
while(arguments[num_arg]) ++num_arg;
if(num_arg == 0) continue;
if(strcmp(arguments[0], "p") == 0) break;
if(strcmp(arguments[0], "r") != 0){
cout<<"No such command"<<endl;
continue;
}
if(num_arg == 1){
}
else if(num_arg != 2 || strlen(arguments[1]) != 1){
cout<<"invalid input"<<endl;
continue;
}
else{
for(; exeNum >= 0; --exeNum){
if(ls[exeNum]->args[0][0] == arguments[1][0]){
break;
}
}
}
if(exeNum >= 0){
ls[exeNum]->show();
if(ls[exeNum]->erno == -1){
cout<<"It is an error command"<<endl;
}
else{
setup(buffer, ls[exeNum]->args, & (ls[exeNum]->bg));
}
}
}
cout<<"record has quitted"<<endl;
}
int main(void)
{
char inputBuffer[MAX_LINE]; /* buffer to hold the command entered */
int background; /* equals 1 if a command is followed by '&' */
char *args[MAX_LINE/2+1];/* command line (of 80) has max of 40 arguments */
// signal(SIGINT,handle_SIGINT);
while (1){ /* Program terminates normally inside setup */
background = 0;
printf("COMMAND->");
fflush(stdout);
// readSplit(inputBuffer, args, &background);
setup(inputBuffer,args,&background); /* get next command */
}
}
HI!
I am trying to pass whole structure from one program and read it in another using fifo.
I'm using read and write functions. I had a problem with putting my structure into this functions. When I did it and tried to send and receive I get an error (core dump) or I recived some trash. I dont know exactly, where my problem take place (in receiver or sender). How can I send/receive my structure, or what i have wrong in my code.Here is my code...Receiver
struct data
{
char* message;
int size;
vector <times> prog;
};
int if_fifo(char* name)
{
struct stat info;
int score = stat(name,&info);
if(S_ISFIFO(info.st_mode))
{
return 1;
}
else
{
return 0;
}
}
int fifo_in(char* name)
{
data msg;
int pip;
pip = open(name, O_RDONLY | O_NONBLOCK);
while(1)
{
int hr = read(pip,&msg,sizeof(msg));
if(hr != 0)
{
cout << "Message: " << msg.message << endl;
}
}
cout << "O.K." << endl;
return 0;
}
int main(int argc, char** argv) {
int c, status_in, status_out;
char* input;
char* output;
float del;
if(argc < 5)
{
cout << "Za malo podanych parametrow" << endl;
return 1;
}
else
{
while ((c = getopt(argc, argv, "iod:")) != -1)
{
switch (c)
{
case 'i':
input = argv[2];
status_in = if_fifo(input);
break;
case 'o':
output = argv[3];
status_out = if_fifo(output);
break;
case 'd':
del = atof(argv[4]);
break;
case '?':
printf("UKNOWN");
}
}
}
if(status_in == 1)
{
return fifo_in(input);
}
else
{
cout << "It isnt fifo!!" << endl;
}
return 0;
}
And sender:
struct data
{
char* message;
int size;
vector <times> prog;
}msg;
int if_fifo(char* name)
{
struct stat info;
int score = stat(name,&info);
if(S_ISFIFO(info.st_mode))
{
return 1;
}
else
{
return 0;
}
}
int fifo_out(char* name)
{
msg.message = "To jest to!!";
msg.size = sizeof(msg.message);
int pip;
pip = open(name, O_WRONLY);
if( pip == -1 )
{
perror("Error: open( ): ");
return 1;
}
write(pip,&msg,sizeof(msg));
return 0;
}
int main(int argc, char** argv) {
int c, status_out;
char* output;
if(argc < 3)
{
cout << "Za malo podanych parametrow" << endl;
return 1;
}
else
{
while ((c = getopt(argc, argv, "o:")) != -1)
{
switch (c)
{
case 'o':
output = argv[2];
status_out = if_fifo(output);
break;
case '?':
printf("UKNOWN");
}
}
}
if(status_out == 1)
{
return fifo_out(output);
}
return 0;
}
you cannot just send memory structures from one program to another. You have to do whats called 'serialization' ie convert the struct into a byte stream that represents the structure. There are many, many serialization techniques: ASN1/ Ber, XML, JSON, Google protocol buffs, roll your own.
Just so you know why this is. The field message in your struct is actually a pointer, when you send this pointer to another program it points to the same address but in the receiver prgram not the sender. That address likely doesnt exist and certainly does not contain the string you had in the sender program.
I am trying to detect the drive letter in Windows. Drive is a primary drive in second IDE channel. I am using GetLogicalDrives().
But this does not tell me I am accessing IDE primary drive.
Here is an example:
#include <cstdint>
#include <windows.h>
#include <cstdio>
const char* GetTypeOfDrive(const char* Drive)
{
const char* Result = NULL;
unsigned int DriveType = GetDriveType(Drive);
switch(DriveType)
{
case DRIVE_FIXED:
Result = "Hard disk";
break;
case DRIVE_CDROM:
Result = "CD/DVD";
break;
case DRIVE_REMOVABLE:
Result = "Removable";
break;
case DRIVE_REMOTE:
Result = "Network";
break;
default:
Result = "Unknown";
break;
}
return Result;
}
int GetLogicalDrivesList(char Drives[26])
{
int Res = 0;
DWORD DrivesMask = GetLogicalDrives();
for (int I = 0; I < 26; ++I)
{
if (DrivesMask & (1 << I))
{
Drives[Res++] = 'A' + I;
}
}
return Res;
}
int main()
{
char temp[4];
char drives[26];
int drive_count = GetLogicalDrivesList(drives);
for (int i = 0; i < drive_count; ++i)
{
sprintf(temp, "%c:/", drives[i]);
printf("%c is a %s\n", drives[i], GetTypeOfDrive(temp));
}
}
I have a C++ string which contains some characters. How can I change the char colour if I meet certain chars? Below is the sample code:
#include <iostream>
#include "windows.h"
using namespace std;
int main()
{
HANDLE h;
h = GetStdHandle(STD_OUTPUT_HANDLE);
string str = "my name is meow.";
for(int i=0; i<str.length(); i++)
{
if(str[i] == 'm')
{
//change the char 'm' to red color..
}
cout<<str[i];
}
return 0;
}
if(str[i] == 'm')
{
SetConsoleTextAttribute(h, FOREGROUND_RED);
cout<<str[i];
}
else
{
SetConsoleTextAttribute(h, 15);
cout<<str[i];
}
maybe this is what you wanna do?
it need a way to call function whose name is stored in a string similar to eval. Can you help?
C++ doesn't have reflection so you must hack it, i. e.:
#include <iostream>
#include <map>
#include <string>
#include <functional>
void foo() { std::cout << "foo()"; }
void boo() { std::cout << "boo()"; }
void too() { std::cout << "too()"; }
void goo() { std::cout << "goo()"; }
int main() {
std::map<std::string, std::function<void()>> functions;
functions["foo"] = foo;
functions["boo"] = boo;
functions["too"] = too;
functions["goo"] = goo;
std::string func;
std::cin >> func;
if (functions.find(func) != functions.end()) {
functions[func]();
}
return 0;
}
There are at least 2 alternatives:
The command pattern.
On windows, you can use GetProcAddress to get a callback by name, and dlopen + dlsym on *nix.
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
double eval( string expression );
int main( int argc, char *argv[] )
{
string expression = "";
for ( int i = 1; i < argc; i++ )
{
expression = expression + argv[i];
}
cout << "Expression [ " << expression << " ] = " << endl;
eval( expression );
}
double eval( string expression )
{
string program = "";
program = program + "#include <cmath>\n";
program = program + "#include <iostream>\n";
program = program + "using namespace std;\n";
program = program + "int main()\n";
program = program + "{\n";
program = program + " cout << ";
program = program + expression;
program = program + " << endl;\n";
program = program + "}";
ofstream out( "abc.cpp" );
out << program;
out.close();
system( "g++ -o abc.exe abc.cpp" );
system( "abc" );
}
You could try to adopt an existing scripting engine, expose the functions you like to this and then use this to evaluate your statements. One such enging could be the V8 engine: https://developers.google.com/v8/intro but there are many alternatives and different languages to choose from.
Here are some examples:
Boost Python
V8
LUA
AngelScript
Except using the function map in the program and hack it on the Makefile, you can access it through ELF.
I think this method is better as it did not need to write duplicate code and compile it every time on different machine.
Here is my demo C/C++ equivalent of eval(“function(arg1, arg2)”)
#include<stdio.h>
#include<stdlib.h>
#include<elf.h>
#include<libelf.h>
#include<unistd.h>
#include<fcntl.h>
#include<gelf.h>
#include<string.h>
void my_fun()
{
int a = 19;
printf("my_fun is excute, a is %d \n", a);
}
void my_fun2()
{
printf("my_fun2 is excute\n");
return;
}
void my_fun3()
{
return;
}
void excute_fun(char *program_name, char *function_name)
{
int i, count;
Elf32_Ehdr *ehdr;
GElf_Shdr shdr;
Elf *elf;
Elf_Scn *scn = NULL;
Elf_Data *data;
int flag = 0;
int fd = open(program_name, O_RDONLY);
if(fd < 0) {
perror("open\n");
exit(1);
}
if(elf_version(EV_CURRENT) == EV_NONE) {
perror("elf_version == EV_NONE");
exit(1);
}
elf = elf_begin(fd, ELF_C_READ, (Elf *) NULL);
if(!elf) {
perror("elf error\n");
exit(1);
}
/* Elf32_Off e_shoff; */
/* if ((ehdr = elf32_getehdr(elf)) != 0) { */
/* e_shoff = ehdr->e_shoff; */
/* } */
/* scn = elf_getscn(elf, 0); */
/* printf("e_shoff is %u\n", e_shoff); */
/* scn += e_shoff; */
while ((scn = elf_nextscn(elf, scn)) != NULL) {
gelf_getshdr(scn, &shdr);
if (shdr.sh_type == SHT_SYMTAB) {
/* found a symbol table. */
break;
}
}
data = elf_getdata(scn, NULL);
if(!shdr.sh_entsize)
count = 0;
else
count = shdr.sh_size / shdr.sh_entsize;
for (i = 0; i < count; ++i) {
GElf_Sym sym;
gelf_getsym(data, i, &sym);
char *sym_name = elf_strptr(elf, shdr.sh_link, sym.st_name);
if(sym_name != NULL && sym_name[0] != '_' && sym_name[0] != '\0' && sym_name[0] != ' ' && sym.st_value != 0)
{
/* printf("sym_name is %s\n", sym_name); */
/* printf("%s = %X\n", elf_strptr(elf, shdr.sh_link, sym.st_name), sym.st_value); */
if(!strcmp(sym_name, function_name)) {
void (*fun)(void) = (void*)sym.st_value;
(*fun)();
flag = 1;
}
}
}
if(!flag)
printf("can not find this function\n");
elf_end(elf);
close(fd);
}
int main(int argc, char *argv[])
{
char *input = (char*)malloc(100);
for(;;) {
printf("input function_name to excute: ");
scanf("%s", input);
excute_fun(argv[0], input);
memset(input, 0, sizeof(input));
printf("\n");
}
free(input);
return 0;
}
This implementation is based on Example of Printing the ELF Symbol Table