CodeEval挑战:反转输入文件中的字符串
CodeEval Challenge: Reverse strings in input file
我决定在明年正式上课之前开始学习C++,我已经开始学习CodeEval和Project Euler上的一些简单挑战。在本例中,您必须获取一个包含字符串的输入文件,并且您必须输出具有反转单词的文件行。这样一个具有以下输入的文件
1:这是第一行
2:这是的第二行
最终会成为
1:一行是这个
2:两行是这个
我写了下面的程序来实现这一点,除了没有正确地反转字符串,而是完全反转单词之外,尽管编译时没有错误或警告,它还是会出现分段错误。我想我错过了一些关于C++中正确内存管理的东西,但我不确定它是什么。那么有人能告诉我在这方面我错过了什么吗?
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
int main(int argc, char** argv)
{
std::string filename = argv[1]; //has to be argv[1], argv[0] is program name
std::string output_string; //final output
std::string line; //Current line of file
std::ifstream read(filename.c_str());
if(read.is_open()){
while(std::getline(read,line)){
std::string temp;
std::istringstream iss;
iss.str(line);
while(iss >> temp){ //iterates over every word
output_string.insert(0,temp); //insert at the start to reverse
output_string.insert(0," "); //insert spaces between new words
}
output_string.erase(0,1); //Removes the space at the beginning
output_string.insert(0,"n"); //Next line
}
output_string.erase(0,1); //Remove final unnecessary n character
read.close();
}
else{
std::cout<<"Unable to open filen";
}
for(unsigned int i = output_string.length(); i>=0;i--){
std::cout<<output_string[i];
}
std::cout<<"n";
}
for(unsigned int i = output_string.length(); i>=0;i--){
std::cout<<output_string[i];
}
segfault发生在这里;您可能能够从编译器中获得带有一些附加标志的警告。例如,g++不使用-Wall
产生警告,但使用-Wextra
产生两个警告:一个关于argc
未被使用,另一个关于该循环从未终止。
这里的问题有两个:正如长颈鹿船长所说,你的出发点超出了实际长度;而且条件i >= 0
将始终为真,因为i
是无符号的。因此,一旦它达到0,下一次递减将使它循环到尽可能高的值,然后您肯定获得越界内存访问。
报告的警告为:
reverse.cpp:31:49: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
for(unsigned int i = output_string.length(); i>=0;i--){
正如Giraffe上尉所说,你正在反转整个文件,而不仅仅是每一行。因此,您可以反转每一行,并在完成该行后输出,而不是存储整个输出以备以后使用。
以下是整个程序,只做了最小的更改,以避免任何警告并获得正确的输出。主要的变化是将output_string
的所有使用转移到读取循环中。
int main(int argc, char** argv)
{
if (argc != 2)
{
std::cerr << "Need a file to process!" << std::endl;
return 1;
}
std::string filename = argv[1]; //has to be argv[1], argv[0] is program name
std::string line; //Current line of file
std::ifstream read(filename.c_str());
if(read.is_open()){
while(std::getline(read,line)){
std::string output_string; //final output
std::string temp;
std::istringstream iss;
iss.str(line);
while(iss >> temp){ //iterates over every word
output_string.insert(0,temp); //insert at the start to reverse
output_string.insert(0," "); //insert spaces between new words
}
output_string.erase(0,1); //Removes the space at the beginning
std::cout << output_string << std::endl;
}
read.close();
}
else{
std::cout<<"Unable to open filen";
}
}
将最后一个for语句更改为
std::cout << output_string;
通过在输出字符串的最后一个之后打印字符开始输出。这消除了segfault。现在您正试图反向打印反向输出。
现在您发现应该只反转每一行,而不是整个文本。您可以很容易地做到这一点,方法是在插入中为每一行添加一个起始索引,而不是0。
所以不是
output_string.insert(0,temp); //insert at the start to reverse
你可以做
output_string.insert(start_of_line, temp); //insert at the start to reverse
- 将字符指针十六进制转换为字符串并保存在文本文件C++中
- 有没有办法从非C/C++文件中读取C++原始字符串文字的内容
- 如何打开并写入一个名称取自C++中字符串的文件
- 如何从二进制文件中读取字符串
- 如何在 c++ 中使用 getline 从文件中读取字符串?
- 将字符串与文件上的数据进行比较
- 用户输入字符串的文件附加问题..C++
- 如何从文件中读取两个字符串和数字数组,并将它们存储在对象向量中
- 如何使字符串出现在编译的二进制可执行文件的开头?
- 使用文件内容作为硬编码字符串
- 将文件复制到自定义位置,存在字符串转换问题
- 在 c++ 中连接字符串和整数,以便在 C++ 11 不支持计算机的情况下读取多个文件
- 声明要在 qml 和 cpp 文件中使用的全局字符串
- C 通过char读取文件字符串的文件char;崩溃
- 我不明白如何将 toupper 和 isalpha 与.txt文件字符串输入一起使用
- 在 CPP 文件中使用 make 文件字符串变量
- 编译 PyGAMMA Mac Lion:g++ 找不到标准的 C++ 头文件(字符串/iostream..)
- 如何在c++中使用文件字符串作为命令
- 使用 TinyXML 解析 XML 文件字符串
- 递归下降解析器帮助(不读取文本文件字符串)