我正在尝试编写一个程序,它在运行时接受多个参数以将文本附加到文件中。
程序在运行时产生分段错误。这是代码:
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;
}
我还是一个初学者,我在理解c字符串时遇到了很大的麻烦。 char *和char []和char * []之间有什么区别?
更新:
代码仍然会引发分段错误,这是我修改过的代码:
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;
}
答案 0 :(得分:6)
char* filename[64]
创建一个包含64个指针的数组。您打算为包含64个字符的字符串创建空间 - 这将是char filename[64]
。因为你只为指针分配了空间,并且从未使指针指向任何内存,所以会出现seg错误。
解决方案:使用char filename[64];
这会为您的字符串创建一个64字节的块;值filename
指向此块的开头,可用于复制操作
strcpy(filename, argv[2]);
我强烈建议使用“复制不超过n个字符”的功能 - 这可以防止一个非常长的参数导致缓冲区溢出。因此
strncpy(filename, argv[2], 64);
会更安全。更好的
strncpy(filename, argv[2], 63);
filename[63] = '\0';
这可以保证复制的字符串以空值终止。
message
存在同样的问题。我认为你不需要重复代码...
如果您需要更多信息,请与我们联系。
<强>更新强>
今天我了解了strlcpy
的存在 - 见this answer。即使原始字符串长于分配的空间,它也会包含NUL
字符串终止符。有关更完整的讨论,请参阅this,包括所有编译器无法使用此功能的原因(如果您尝试编写可移植代码,这当然是一个主要缺点)。
答案 1 :(得分:3)
由于您已将其标记为C ++(并且尚未提及它):
argv
已经是一个C风格的数组,所以不需要将它复制到另一个(除非你只是想浪费空间)。如果您真的想将其复制到某个内容中,std::string
对象将是更好的方法:
int main(int argc, char* argv[])
{
// assuming your conditional checks are already done here ...
std::string filename = argv[1];
std::string message = argv[2];
// do something
return 0;
}
答案 2 :(得分:2)
您的变量filename
和message
是char
指针数组,而不是C风格的字符串(应该是以null结尾的char
数组)。所以你需要将它们的类型声明为:
char filename[64];
char message[256];
并使用strcpy
作为:
strcpy(filename, argv[2]);
strcpy(message, argv[3]);
对open
的调用类似:
fd = open(filename, O_RDWR | O_CREAT, 00000);
答案 3 :(得分:2)
&GT;&GT;&GT;我仍然是一个初学者,我在理解c字符串时遇到了很大的麻烦。 char 和char []以及char * []之间的区别是什么?*
第一次遇到指针时,指针很难理解。
当你有一个变量文件名时,* filename取消引用该变量,这意味着它不是指针,而是指向的东西。
你们大部分时间都是正确的。问题是你对如何使用指针缺乏明确性。这是你的代码,修改了一下工作。我注释掉了破损的部分,以便您可以将破碎与固定比较。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int
main(int argc, char* argv[])
{
//char* filename[64];
//char* message[256];
char filename[64]; //declare filename, point it at char[64]
char message[256]; //declare message, point it at char[256]
int fd; //file descriptor
printf("argc %d\n",argc);
//error checking
if ( (argc < 1) || (argc > 4) )
{
//cout << "Usage: -c(optional - clear file contents) <Filename>, message to write" << endl;
printf("Usage: -c(optional - clear file contents) <Filename>, message to write\n");
exit(EXIT_FAILURE);
}
int argi=1;
if( !strcmp(argv[argi],"-c") ) { argi++; } //clear
//set variables to command arguments depending if -c option is specificed
if (argc == 4)
{
//strcpy(*filename, argv[argi++]);
//strcpy(*message, argv[argi++]);
strcpy(filename, argv[argi++]);
strcpy(message, argv[argi++]);
}
else
{
//strcpy(*filename, argv[argi++]);
//strcpy(*message, argv[argi++]);
strcpy(filename, argv[argi++]);
strcpy(message, argv[argi++]);
}
//fd = open(*filename, O_RDWR | O_CREAT, 00000); //open file if it doesn't exist then create one
if( !(fd = open(filename, O_RDWR | O_CREAT, 00000)) ) //open file if it doesn't exist then create one
{
//always check for failure to open
//and emit error if file open fails
exit(EXIT_FAILURE);
}
//fchmod(fd, 00000);
write(fd,message,strlen(message));
return 0;
}
答案 4 :(得分:0)
我还是一个初学者,我在理解c字符串时遇到了很大的麻烦。 char *和char []和char * []之间有什么区别?
对明确问题的简短回答是char*
和char[]
都可以用作C字符串。另一方面,char* []
是一个C-strings
的数组。