在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
没有给出数字数组中的元素;这样做的惯用方法是使用 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;
与您的直接问题无关的几点可能值得一提的是:
类类型通常通过引用 const 传递,而不是通过价值。 这可以说是过早的优化,但事实确实如此无处不在,其他任何东西都让人想知道为什么。
函数中未更改的值应声明为
const
和static
.std::string
支持==
和!=
;如果你正在寻找平等,这就是你应该使用的。compare
函数真的应该仅用于词典排序。从循环中间返回是您通常想要的避免。 当然,当函数如此简单时,它真的不是重要,但这是一个坏习惯。
这只是与所讨论的功能有关。 在main
,你也有sizeof
的问题. 在这种情况下,看起来您是尝试使用它来确定文件中的字数。 那如果不实际读取文件,则无法完成。 您在这里需要的是 std::vector<std::string>
,而不是 C 样式数组(其大小必须为编译时已知(。
当然:if
所需的类型是 bool
. isArticle
返回一个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
。
sizeof
运算符不返回数组中的元素数。 它返回数组占用的内存空间。 char
数组将具有与int
数组不同的sizeof
。
对于数组,您可以通过以下方式在编译时确定元素的数量:
const unsigned int elements_in_array =
sizeof(article) / sizeof(article[0]);
- 内存错误低于在C++年实现埃拉托色尼筛分时的预期
- 将 vector<vector<int>> 传递到函数中会产生内存错误
- 为什么删除分配的阵列会导致内存错误?
- 自定义哈希表实现-将字符串映射到整数时出现内存错误
- 需要找到3个小错误-内存错误
- 从'deleted function'获取内存错误
- OpenGL, GLFW, GLAD. glViewport(0, 0, 800, 600) 抛出内存错误
- 销毁 std::queue 会导致内存错误
- 加速进程间:管理共享内存错误
- 删除映射中的指针会导致内存错误
- 由于从 std::map 派生的类中的 std::map 迭代器导致的内存错误
- 当我用clang编译代码时,GCOV会出现内存错误
- 查找素数和时出现内存错误
- 循环链表的内存错误:未分配正在释放的指针
- 为什么我会因Valgrind遇到内存错误?(C ,抽象语法树评估)
- 我如何解析包含65k行的代码的文件,导致[BCC32致命错误] F1008出于内存错误
- 动态内存错误
- 内存错误C 私有INT
- 无法在 Mac OS X 上分配内存错误 - java(xx,xx) malloc: *** mmap(size=XX)
- 类对象的可变级别内存错误检测