I'm trying to write a program that takes several arguments at runtime to append text to a file.
The program produces a segmentation fault at runtime. Here is the code:
int main(int argc, char* argv[])
{
//error checking
if (argc < 1 || argc > 4) {
cout << "Usage: -c(optional - clear file contents) <Filename>, message to write" << endl;
exit(EXIT_FAILURE);
}
char* filename[64];
char* message[256];
//set variables to command arguments depending if -c option is specificed
if (argc == 4) {
strcpy(*filename, argv[2]);
strcpy(*message, argv[3]);
} else {
strcpy(*filename, argv[1]);
strcpy(*message, argv[2]);
}
int fd; //file descriptor
fd = open(*filename, O_RDWR | O_CREAT, 00000); //open file if it doesn't exist then create one
fchmod(fd, 00000);
return 0;
}
I am still quite a beginner and I'm having immense trouble understanding c strings. What's the difference between char* and char[] and char* []?
UPDATE:
The code still throws a segmentation fault, here is my revised code:
using std::cout;
using std::endl;
int main(int argc, char* argv[])
{
//error checking
if (argc < 1 || argc > 4) {
cout << "Usage: -c(optional - clear file contents) <Filename>, message to write" << endl;
exit(EXIT_FAILURE);
}
char filename[64];
char message[256];
//set variables to command arguments depending if -c option is specificed
if (argc == 4)
{
strncpy(filename, argv[2], 64);
strncpy(message, argv[3], 256);
}
else
{
strncpy(filename, argv[1], 64);
strncpy(message, argv[2], 256);
}
int fd; //file descriptor
fd = open(filename, O_RDWR | O_CREAT, 00000); //open file if it doesn't exist then create one
fchmod(fd, 00000);
return 0;
}
char* filename[64]
creates an array of 64 pointers. You intend to create space for a string with 64 characters - this would be char filename[64]
. Because you only allocated space for pointers, and never made the pointers point to any memory, you get a seg fault.
Solution: use char filename[64];
This creates a block of 64 bytes for your string; the value filename
points to the start of this block and can be used in a copy operation
strcpy(filename, argv[2]);
I would strongly recommend using the "copy no more than n characters" function - this prevents a really long argument from causing buffer overflow. Thus
strncpy(filename, argv[2], 64);
would be safer. Even better
strncpy(filename, argv[2], 63);
filename[63] = '\0';
This guarantees that the copied string is null terminated.
You have the same problem with message
. I don't think you need the code repeating...
Let me know if you need more info.
UPDATE
Today I learnt about the existence of strlcpy
- see this answer. It will take care of including the NUL
string terminator even when the original string was longer than the allocated space. See this for a more complete discussion, including the reasons why this function is not available on all compilers (which is of course a major drawback if you are trying to write portable code).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With