954,492 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

C++ Todo

I have this code:
#include <unistd.h>
#include <iostream>
#include <string>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

void add(char todo[], string priority, string home){
FILE *file;
file = fopen(home.c_str(), "a");
fprintf(file, "%-50s| %-6s\n", todo, priority.c_str());
fclose(file);
}

void list(string home){
string line;
fstream file(home.c_str(),ios::in);
int i = 0;
if (file.is_open()){
while( getline( file, line ) ) {
cout << "[" << i << "] " << line << '\n';
i++;
}
}
file.close();
}

void clear(string home){
FILE *file;
file = fopen(home.c_str(), "w");
fprintf(file, "");
fclose(file);
}

void remove(string home, int n){
string f;
string line;
fstream file(home.c_str(),ios::in);
int i = 0;
if (file.is_open()){
while( getline( file, line ) ) {
if (i != n){
cout << i << '\n' << n << '\n';
files += line;
files += '\n';
}
i++;
}
}
file.close();
clear(home);
fstream fileo(home.c_str(),ios::out);
fileo << f;
}

void help(){
cout << "Usage:\n";
cout << "\tt-do [options]\n";
cout << "Options\n";
cout << "\t-a [TODO]\n";
cout << "\t\tAdd a todo with summary TODO\n";
cout << "\t-l\n";
cout << "\t\tList TODOs\n";
cout << "\t-c\n";
cout << "\t\tClear all TODOs\n";
}
int main (int argc, char* argv[]) {
string home(getenv("HOME"));
string todo = "/.todo.txt";
string priority = "Medium";
home = home + todo;
int opt;
int n;
while ((opt = getopt(argc,argv, "a:p:f:rlhc")) !=EOF ){
switch (opt){
case 'a':
add(optarg, priority, home);
break;
case 'l':
list(home);
break;
case 'c':
clear(home);
break;
case 'r':
n = atoi(optarg);
remove(home, n);
break;
case 'h':
help();
break;
case '?':
help();
break;
}
}
return 0;
}

when run with -r it should remove a line that the user specified, eg:

$t-do -r 1 #Should remove the first line

but it produces a segfault

pymatio
Light Poster
48 posts since Jun 2009
Reputation Points: 10
Solved Threads: 0
 
if (i != n){
                cout << i << '\n' << n << '\n';
                files += line;
                files += '\n';
            }


What is files ? You use that identifier as if it were a string, but it is never declared or defined anywhere.

Tom Gunn
Master Poster
733 posts since Jun 2009
Reputation Points: 1,446
Solved Threads: 135
 

Tom Gunn is right, and another thing, please put the code highlighting, like this: [ code=cplusplus ] ... [ /code ], but without spaces.

Thanks!

Nathan Campos
Junior Poster
190 posts since Jul 2009
Reputation Points: 33
Solved Threads: 6
 

I'm also thinking that this

string todo = "/.todo.txt";

should be "./" instead of "/.".

dwks
Posting Whiz in Training
269 posts since Nov 2005
Reputation Points: 185
Solved Threads: 28
 

Huh, now i'm thinking the same!

Nathan Campos
Junior Poster
190 posts since Jul 2009
Reputation Points: 33
Solved Threads: 6
 

files should be f & it is "/.todo" because this makes it a hidden file in Linux

pymatio
Light Poster
48 posts since Jun 2009
Reputation Points: 10
Solved Threads: 0
 

Huh, it's hidden, now i understand!

Nathan Campos
Junior Poster
190 posts since Jul 2009
Reputation Points: 33
Solved Threads: 6
 

Yes, but "/.todo" is a hidden file *in the root of the drive*, and it's extremely probable that you don't want to be writing there. If you want a hidden file, fine, use ".todo" or "./todo" to reference the file ".todo" in the current working directory.

dwks
Posting Whiz in Training
269 posts since Nov 2005
Reputation Points: 185
Solved Threads: 28
 

But the path will be "/home/USER/.todo"

pymatio
Light Poster
48 posts since Jun 2009
Reputation Points: 10
Solved Threads: 0
 

Well then use "/home/USER/.todo" or better yet "~/.todo". Saying "/.todo" is like saying "/usr" or "/home"; it gets you a file relative to the root of the filesystem, which as I have said before, is definitely not what you want.

dwks
Posting Whiz in Training
269 posts since Nov 2005
Reputation Points: 185
Solved Threads: 28
 

I'm adding '/.todo' to a string with ~/ in - I know that / is root, I sure it says this in the code!

Anyways can we get back to my question

pymatio
Light Poster
48 posts since Jun 2009
Reputation Points: 10
Solved Threads: 0
 

I tried to compile that with vc++ 2008 Express on MS-Windows and got the following error. Maybe that is why your program seg faults, because there were compile errors that you failed to fix
1>c:\dvlp\test1\test1\test1.cpp(52) : error C2065: 'files' : undeclared identifier
1>c:\dvlp\test1\test1\test1.cpp(53) : error C2065: 'files' : undeclared identifier

[edit]see post #6, which answered that problem a 6 days ago ago![/edit]

Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 

> string home(getenv("HOME"));
Does this actually return a true path - one that starts with / ?

Because I see lots of ~ flying about, and programs do NOT expand ~ automagically for you (that's what the shell does).

Salem
Posting Sage
Team Colleague
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
 

> string home(getenv("HOME"));
Also, it will crash when getenv() returns NULL; Better to make that two statements so that you can check for NULL.

>>"a:p:f:rlhc"
I had to add another colon after the r in order to make that work right. "a:p:f:r:lhc"


Why are you mixing FILE and fstream in the same program? Since this is a c++ program you should replace FILE with fstream.

Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You