在 C++ 程序中读取命令行参数时出现内存错误
Getting memory fault when reading command line arguments in a C++ program
我一直在为学校编写一个 C++ 代码项目,它希望我从命令行参数读取文本文件并将其输出,同时在任何文章 [a,an,the 之后添加在命令行中声明的形容词].这是我第一次必须使用命令行进行任何项目。
我已经设法从命令行获取并读取文本文件,但我的问题是当我想获取一个字符串作为函数 isArticle() 的参数时,我在 UNIX 中不断收到以下消息shell:
./test-program1[38]: eval: line 1: 7704: Memory fault
0a1,4
我不怀疑问题出在 isArticle()
函数上,但问题出在这里:
bool isArticle(string n)
{
string article[]={"a","an","the","A","An","aN","AN","The","tHe","thE","THe","tHE","ThE","THE"};
for(int i=0;i<sizeof(article);i++)
{
if(n.compare(article[i])==0)
return true;
}
return false;
}
虽然还不完整,但这是我用来查看 isArticle() 函数是否正常工作的一些测试代码:
int main(int argc, char *argv[])
{
istream *br;
ifstream file;
if(argc == 1)
br = &cin;
else if(argc==3)
{
file.open(argv[2]);
if(file.is_open())//put work here
{
br=&file;
string word;
string output[sizeof(file)];
while(file>>word)
{
if(isArticle(word)==true)
{
cout<<word;
}
}
}
else
{
usage(argv[2],"Cannot open "+string(argv[2]));
return 1;
}
}
else
{
usage(argv[1], "More than one filename was given");
return 1;
}
return 0;
}
sizeof
运算符不会 return 数组中元素的数量。 return是数组占用的内存space。 char
的数组与 int
的数组具有不同的 sizeof
。
对于您的数组,您可以通过以下方式确定编译时的元素数量:
const unsigned int elements_in_array =
sizeof(article) / sizeof(article[0]);
正如其他人已经指出的那样,sizeof
确实 而不是 给出了数字
数组中的元素;这样做的惯用方法是使用
std::end( article ) - std::begin( article )
。在 C++11 之前的版本中,大多数
有经验的 C++ 程序员会做同样的事情,使用的版本
begin
和 end
来自他们的工具包。
整个 isArticle
函数非常单一。在 C++11 中,
整个函数将是单个库调用:
bool
isArticle( std::string const& word )
{
static std::string const articles[] = {
"a", "an", "the", "A", "An", "aN", "AN",
"The", "tHe", "thE", "THe", "tHE", "ThE", "THE",
};
return std::any_of(
std::begin( articles ), std::end( articles ),
[=]( std::string const& target ) { return word == target; } );
}
在早期的 C++ 中,我们会这样写:
return std::find( begin( articles ), end( articles ), word )
!= end( articles );
(使用我们常用工具包中的 begin
和 end
)。如果我们想要(因为
教学原因)自己编写循环,这将是一些
喜欢:
std::string::const_iterator current = std::begin( articles );
std::string::const_iterator end = std::end( articles );
while ( current != end && *current != word ) {
++ current;
}
return current != end;
可能有几点与您眼前的问题无关
值得一提:
Class 类型通常通过对 const 的引用传递,而不是通过
价值。可以说,这是过早的优化,但确实如此
无处不在,其他任何事情都让人想知道为什么。
函数中未更改的值应声明const
和 static
.
std::string
支持==
和!=
;如果你正在寻找平等,
那就是你应该使用的。 compare
函数真的应该
仅用于字典排序。
从循环中间返回是您通常想要的
避免。当然,当函数这么简单的时候,其实并没有
很重要,但这是一个坏习惯。
这仅涉及相关功能。在main
,你也
sizeof
有问题。在这种情况下,看起来你是
试图用它来确定文件中的单词数。那
如果不实际读取文件就无法完成。你需要的是
std::vector<std::string>
,而不是 C 风格的数组(其大小必须是
在编译时已知)。
当然:if
所需的类型是 bool
。 isArticle
returns 一个 bool
,所以不需要其他任何东西。写作
isArtile( word ) == true
强烈建议你不知道什么是
bool
类型是。 (提示:表达式的类型
isArtile( word ) == true
也是 bool
。)
最后一个建议:如果程序没有参数,你
什么都不做。我认为这不是意图。通常
Unix下命令行进程的解决方案(而且它也很普遍
在 Windows) 下是将所有实际工作放在一个函数中,并编写
类似于:
int
main( int argc, char** argv )
{
if ( argc == 1 ) {
process( std::cin );
} else {
for ( int i = 1; i != argc; ++ i ) {
std::ifstream in( argv[i] );
if ( ! in ) {
// Output error message and set global flag for
// return value...
} else {
process( in );
}
}
}
return globalFlagWithReturnValue;
}
函数process
接受一个std::istream&
作为参数,它
允许它读取 std::cin
或打开的 std::istream
.
我一直在为学校编写一个 C++ 代码项目,它希望我从命令行参数读取文本文件并将其输出,同时在任何文章 [a,an,the 之后添加在命令行中声明的形容词].这是我第一次必须使用命令行进行任何项目。
我已经设法从命令行获取并读取文本文件,但我的问题是当我想获取一个字符串作为函数 isArticle() 的参数时,我在 UNIX 中不断收到以下消息shell:
./test-program1[38]: eval: line 1: 7704: Memory fault
0a1,4
我不怀疑问题出在 isArticle()
函数上,但问题出在这里:
bool isArticle(string n)
{
string article[]={"a","an","the","A","An","aN","AN","The","tHe","thE","THe","tHE","ThE","THE"};
for(int i=0;i<sizeof(article);i++)
{
if(n.compare(article[i])==0)
return true;
}
return false;
}
虽然还不完整,但这是我用来查看 isArticle() 函数是否正常工作的一些测试代码:
int main(int argc, char *argv[])
{
istream *br;
ifstream file;
if(argc == 1)
br = &cin;
else if(argc==3)
{
file.open(argv[2]);
if(file.is_open())//put work here
{
br=&file;
string word;
string output[sizeof(file)];
while(file>>word)
{
if(isArticle(word)==true)
{
cout<<word;
}
}
}
else
{
usage(argv[2],"Cannot open "+string(argv[2]));
return 1;
}
}
else
{
usage(argv[1], "More than one filename was given");
return 1;
}
return 0;
}
sizeof
运算符不会 return 数组中元素的数量。 return是数组占用的内存space。 char
的数组与 int
的数组具有不同的 sizeof
。
对于您的数组,您可以通过以下方式确定编译时的元素数量:
const unsigned int elements_in_array =
sizeof(article) / sizeof(article[0]);
正如其他人已经指出的那样,sizeof
确实 而不是 给出了数字
数组中的元素;这样做的惯用方法是使用
std::end( article ) - std::begin( article )
。在 C++11 之前的版本中,大多数
有经验的 C++ 程序员会做同样的事情,使用的版本
begin
和 end
来自他们的工具包。
整个 isArticle
函数非常单一。在 C++11 中,
整个函数将是单个库调用:
bool
isArticle( std::string const& word )
{
static std::string const articles[] = {
"a", "an", "the", "A", "An", "aN", "AN",
"The", "tHe", "thE", "THe", "tHE", "ThE", "THE",
};
return std::any_of(
std::begin( articles ), std::end( articles ),
[=]( std::string const& target ) { return word == target; } );
}
在早期的 C++ 中,我们会这样写:
return std::find( begin( articles ), end( articles ), word )
!= end( articles );
(使用我们常用工具包中的 begin
和 end
)。如果我们想要(因为
教学原因)自己编写循环,这将是一些
喜欢:
std::string::const_iterator current = std::begin( articles );
std::string::const_iterator end = std::end( articles );
while ( current != end && *current != word ) {
++ current;
}
return current != end;
可能有几点与您眼前的问题无关 值得一提:
Class 类型通常通过对 const 的引用传递,而不是通过 价值。可以说,这是过早的优化,但确实如此 无处不在,其他任何事情都让人想知道为什么。
函数中未更改的值应声明
const
和static
.std::string
支持==
和!=
;如果你正在寻找平等, 那就是你应该使用的。compare
函数真的应该 仅用于字典排序。从循环中间返回是您通常想要的 避免。当然,当函数这么简单的时候,其实并没有 很重要,但这是一个坏习惯。
这仅涉及相关功能。在main
,你也
sizeof
有问题。在这种情况下,看起来你是
试图用它来确定文件中的单词数。那
如果不实际读取文件就无法完成。你需要的是
std::vector<std::string>
,而不是 C 风格的数组(其大小必须是
在编译时已知)。
当然:if
所需的类型是 bool
。 isArticle
returns 一个 bool
,所以不需要其他任何东西。写作
isArtile( word ) == true
强烈建议你不知道什么是
bool
类型是。 (提示:表达式的类型
isArtile( word ) == true
也是 bool
。)
最后一个建议:如果程序没有参数,你 什么都不做。我认为这不是意图。通常 Unix下命令行进程的解决方案(而且它也很普遍 在 Windows) 下是将所有实际工作放在一个函数中,并编写 类似于:
int
main( int argc, char** argv )
{
if ( argc == 1 ) {
process( std::cin );
} else {
for ( int i = 1; i != argc; ++ i ) {
std::ifstream in( argv[i] );
if ( ! in ) {
// Output error message and set global flag for
// return value...
} else {
process( in );
}
}
}
return globalFlagWithReturnValue;
}
函数process
接受一个std::istream&
作为参数,它
允许它读取 std::cin
或打开的 std::istream
.