I'm new to C++, and I'm trying to write a project that interacts through command line. Right now, whenever I run my main (which is the executable), I always receive a segmentation fault error when the main program finished.
Edit comment:
I'm told by tutor to use as little as C++ features such as vectors or strings ... I'm also very new to C++, so i'm trying to utilize as many basic C functions as I can.
I'm
My main function looks like this:
int main(int argc, char** argv) {
cout << "starting mvote..." << endl;
int run_flag = 1;
char* actionBuffer = (char*)malloc(100 * sizeof(char));
char* action = (char*)malloc(16 * sizeof(char));
char* readPtr;
char exit[4] = { 'e','x','i','t' };
//parse command line argumentand get the filename
char* filename = argv[2];
cout << filename;
FILE* fp;
char line[64];
//from here, I'm opening the file and read it by lines
fp = fopen(filename, "r");
if (fp == NULL) {
cout << "file not exists";
return -1;
}
while (fgets(line, 64, fp) != NULL) {
cout << line << "\n";
}
fclose(fp);
while (run_flag == 1) {
cout << "what do you want?\n " << endl;
cin.getline(actionBuffer, 1024);
if (strcmp(actionBuffer, exit) == 0) {
cout << "bye!";
run_flag = 0;
break;
}
//if not exit, Look for the space in the input
readPtr = strchr(actionBuffer, ' ');
int size = readPtr - actionBuffer;
//extract the operation
strncpy(action, actionBuffer, size);
for (int i = 0; i < size; i++) {
cout << "operation:" << action[i];
}
// depend on the operation specified before the first empty space
run_flag = 0;
}
free(actionBuffer);
free(action);
return 0;
}
Description:
I first try to open up a csv file which lies in the same folder as main, and I read the file line by line. Then, I just implement a simple command where you can type exit and quit the program.
I allocate two memory, actionBuffer and action, which are used to hold command
Problem: a segmentation fault [core dumped] always exists when I type exit and hit enter, and then the process finished.
Research: So I learned that segmentation fault is due to accessing a memory that does not belongs to me. But where in my program am I trying to access such a memory?
Any advice is appreciated! Thank you.
Just to give you an idea, this would be an example of C++ code
#include<iostream>
#include<fstream>
#include<string_view>
#include<string>
#include<sstream>
#include<exception>
int main(int argc, char** argv) {
std::cout << "starting mvote...\n";
//parse command line argumentand get the filename
std::string filename = argv[2]; // NO CHECKS!
std::cout << filename <<'\n';
//from here, I'm opening the file and read it by lines
{
std::ifstream ifs(filename);
if (!ifs) {
throw std::invalid_argument("file not exists");
}
std::string line;
while (std::getline(ifs, line)) {
std::cout << line << '\n';
}
}
bool run_flag = true;
while (run_flag) {
std::cout << "what do you want?\n";
std::string userInput;
std::getline(std::cin, userInput);
if (userInput == "exit") {
std::cout << "bye!\n";
return 0;
}
std::stringstream userInputSs(userInput);
std::string operation;
while(userInputSs >> operation){
std::cout << "operation: " << operation << '\n';
}
}
}
Related
For my formation, an exercise ask us to create a program similar to the linux 'cat' command.
So to read the file, i use an ifstream, and everything work fine for regular file.
But not when i try to open /dev/ files like /dev/stdin: the 'enter' is not detected and so, getline really exit only when the fd is being closed (with a CTRL-D).
The problem seems to be around how ifstream or getline handle reading, because with the regular 'read' function from libc, this problem is not to be seen.
Here is my code:
#include <iostream>
#include <string>
#include <fstream>
#include <errno.h>
#ifndef PROGRAM_NAME
# define PROGRAM_NAME "cato9tails"
#endif
int g_exitCode = 0;
void
displayErrno(std::string &file)
{
if (errno)
{
g_exitCode = 1;
std::cerr << PROGRAM_NAME << ": " << file << ": " << strerror(errno) << std::endl;
}
}
void
handleStream(std::string file, std::istream &stream)
{
std::string read;
stream.peek(); /* try to read: will set fail bit if it is a folder. */
if (!stream.good())
displayErrno(file);
while (stream.good())
{
std::getline(stream, read);
std::cout << read;
if (stream.eof())
break;
std::cout << std::endl;
}
}
int
main(int argc, char **argv)
{
if (argc == 1)
handleStream("", std::cin);
else
{
for (int index = 1; index < argc; index++)
{
errno = 0;
std::string file = std::string(argv[index]);
std::ifstream stream(file, std::ifstream::in);
if (stream.is_open())
{
handleStream(file, stream);
stream.close();
}
else
displayErrno(file);
}
}
return (g_exitCode);
}
We can only use method from libcpp.
I have search this problem for a long time, and i only find this post where they seems to have a very similar problem to me:
https://github.com/bigartm/bigartm/pull/258#issuecomment-128131871
But found no really usable solution from them.
I tried to do a very ugly solution but... well...:
bool
isUnixStdFile(std::string file)
{
return (file == "/dev/stdin" || file == "/dev/stdout" || file == "/dev/stderr"
|| file == "/dev/fd/0" || file == "/dev/fd/1" || file == "/dev/fd/2");
}
...
if (isUnixStdFile(file))
handleStream(file, std::cin);
else
{
std::ifstream stream(file, std::ifstream::in);
...
As you can see, a lot of files are missing, this can only be called a temporary solution.
Any help would be appreciated!
The following code worked for me to deal with /dev/fd files or when using shell substitute syntax:
std::ifstream stream(file_name);
std::cout << "Opening file '" << file_name << "'" << std::endl;
if (stream.fail() || !stream.good())
{
std::cout << "Error: Failed to open file '" << file_name << "'" << std::endl;
return false;
}
while (!stream.eof() && stream.good() && stream.peek() != EOF)
{
std::getline(stream, buffer);
std::cout << buffer << std::endl;
}
stream.close();
Basically std::getline() fails when content from the special file is not ready yet.
I'm trying to create a program that passes a file to a function. The function is supposed to detect how many lines are in my file. I don't think I'm passing the file correctly into my function, I've tried several different ways. Any help will be greatly appreciated.
#include <iostream>
#include <fstream>
#define die(errmsg) {cerr << errmsg << endl; exit(1);}
using namespace std;
int num_of_lines(ifstream file)
{
int cnt3;
string str;
while(getline(file, str))cnt3++;
return(cnt3);
}
int main(int argc, char **argv)
{
int num_of_lines(ifstream file);
string file;
file = argv[1];
if(argc == 1)die("usage: mywc your_file"); //for some reason not working
ifstream ifs;
ifs.open(file);
if(ifs.is_open())
{
int a;
cout << "File was opened\n";
a = num_of_lines(file);
cout <<"Lines: " << a << endl;
}
else
{
cerr <<"Could not open: " << file << endl;
exit(1);
}
ifs.close();
return(0);
}
Two problems with the function. First, you should pass the stream by reference. Second, you just forgot to initialise your counter.
int num_of_lines( ifstream &file )
{
int cnt3 = 0;
string str;
while( getline(file, str) ) cnt3++;
return cnt3;
}
The other thing is you're passing file to it (which is a string) instead of ifs. Change the call to:
a = num_of_lines( ifs );
How can I print the contents of a file, the name of which is specified via my program's command line?
I do not know how to give the name of file by command line and how to work with it.
For ex this is does not work:
int main(int argc, char *argv[])
{
FILE *f;
char s[20];
cin >> s;
f=fopen_s(s,"rt");
std::cout << f;
_getch();
return 0;
}
error C2660
#include <iostream>
#include <fstream>
int main(int argc , char *argv[])
{
if(argc < 2)
{
std::cout << " Wrong usage " << std::endl;
exit(0);
}
std::string file_name = argv[1];
std::ifstream fs;
fs.open(file_name.c_str());
std::cout << file_name << std::endl;
std::string line ;
while(fs >> line)
{
std::cout << line << std::endl;
}
return 0;
}
You cannot use << operator with char[]
Solution : You can use std::string
std::string s;
Use the string's c_str() value as name in fopen_s(name, "rt")
Solution : You need to put the file in the same directory as the executable
f = fopen_s(s.c_str(), "rt");
You cannot cout << FILE *f
Solution : read file content line by line as you print each line
char* line; //used to receive data for each line
int length; //used to represent how many characters have received
while ((getline(&line, &length, f) != -1) {
print("%s", line);
}
Hi i try to make code in c++. This code only makes text file easy encrypted and save into a new file. And when i compile this code antivirus says, it is virus/spyware Gen:Variant.Kazy.20825. I dont know why it is virus.
Here is my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void controlParameters(int argc){ //check if input parameters are ok
if(argc == 1){
cout << "Pokud chcete text zasifrovat, spustte program s parametrem: -enc \"Nazev_souboru.txt\"\n";
cout << "Pokud ho chcete desifrovat, spustte program s parametrem: -dec \"Nazev_souboru.txt\"\n";
}else if(argc > 3){
cout << "Moc parametru. Spustte si program bez parametru.\n";
}else if(argc < 3){
cout << "Chybi jeden parametr. Spustte si program bez parametru.\n";
}else{
cout << "Vsechno vypada zatim dobre\n";
}
}
void encryption(string &file); //encrypt text file
void decryption(string &file); //decrypt text file
bool controlFile(string &file); //check if file can be opened
int main(int argc, char **argv){
controlParameters(argc);
string file;
file = argv[2];
if(controlFile(file)){
}else{
cout << "Soubor nesel nacist." << endl;
return -1;
}
cout << "Ukonceno.\nZmacknete ENTER pro pokracovani..."<<endl;
cin.get();
return 0;
}
bool controlFile(string &file){
ifstream ifs;
ifs.open(file);
if(ifs.is_open()){
ifs.close();
return true;
}else{
ifs.close();
return false;
}
}
void encryption(string &file){
ifstream ifs;
ofstream ofs;
string line;
ifs.open(file);
ofs.open("encrypt.txt");
if(ifs.is_open()){
while(!ifs.eof()){
getline(ifs,line);
int a = line.length();
int i = 0;
while(i < a){
ofs << ((char)(line[i]^100));
}
line.clear();
ofs << "\n";
}
}else{
cout << "Nelze nacist soubor" << endl;
}
}
void decryption(string &file){
ifstream ifs;
ofstream ofs;
string line;
ifs.open(file);
ofs.open("decrypt.txt");
if(ifs.is_open()){
while(!ifs.eof()){
getline(ifs,line);
int a =line.length();
int i = 0;
while(i < a){
ofs << ((char)(line[i]^100));
}
line.clear();
ofs << "\n";
}
}else{
cout << "Nelze nacist soubor" << endl;
}
}
It's good practice to exclude your source-control directories from virus scanners; they can cause performance and locking problems even if there are no false positives while performing source-control actions or compiling (I've seen it happen several times).
So if only to make your programming experience more reliable, disable the virus scanner on those directories.
You may still want to scan the final, released version of your executable to help avoid false positives: after all, even if it's not your fault the virus scanner chokes, it's not a good impression to leave behind on a user.
Antivirus software uses "heuristics" to determine what is a virus and what isn't. So it looks for patterns in the file that does things that it finds suspicious. I can't see anything directly wrong in your code, so I suspect it's a "false-positive". I personally don't like antivirus software, it causes more problems than it solves...
By the way, you could add the "output filename" to your encrypt/decrypt function, and make them one function! ;)
I try to read file /proc/'pid'/status, using c program. The code is as follows, and even I use sudo to run it, the prompt still keeps throwing "Unable to open file". Please let me know if you have any ideas on how to fix this. thanks
Richard
...
int main (int argc, char* argv[]) {
string line;
char* fileLoc;
if(argc != 2)
{
cout << "a.out file_path" << endl;
fileLoc = "/proc/net/dev";
} else {
sprintf(fileLoc, "/proc/%d/status", atoi(argv[1]));
}
cout<< fileLoc << endl;
ifstream myfile (fileLoc);
if (myfile.is_open())
{
while (! myfile.eof() )
{
getline (myfile,line);
cout << line << endl;
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
Avoid using C strings in C++. You forgot to allocate this one. A stringstream will allocate for you and has sprintf functionality.
int main (int argc, char* argv[]) {
string line;
ostringstream fileLoc;
if(argc != 2)
{
cout << "a.out file_path" << endl;
fileLoc << "/proc/net/dev";
} else {
fileLoc << "/proc/" << argv[1] << "/status";
}
cout<< fileLoc.str() << endl;
ifstream myfile (fileLoc.str().c_str());
You have not allocated memory for the char array pointed by fileLoc
char* fileLoc; // just a char pointer...pointing to some random location.
.
.
sprintf(fileLoc, "/proc/%d/status", atoi(argv[1]));
Allocate the array dynamically and free it later or you can use a static array with suitable size or even better use the C++ string.