正如标题所示,我在将字符串转换为字符数组时遇到了一些麻烦。
首先让我明白为什么我需要这样做,因为如果我的做法错了,我会很乐意采取不同的做法。 (虽然我更喜欢答案可以直接关注手头的问题)
我有一个包含多行的文件。每行的格式为
b 12 3 4
d 4 1 5.71
...
我要做的是读取每一行(使用getLine并将其保存在字符串变量上)并将它们拆分为空格,以便将每个字母/数字分开。
为了实现这一点,我采用了strtok方法,该方法将char *作为参数
这种转换是出错的地方。
我采取了几种方法,但总是以同样的方式结束:
尝试#1 - .data()
const char *converted = new char[(line.size()+1)];
//The sentence is complete in this cout!
cout << line << " -printed string\n";
converted = line.data();
converted[line.size()] = '\0';
//sentence no longer complete!
cout << converted << " -printed char array\n";
尝试#2 .c_str()
char *converted;
//The sentence is complete in this cout!
cout << line << " -printed string\n";
converted = (char*)line.c_str();
//sentence no longer complete!
cout << converted << " -printed char array\n";
尝试#3 copy()
char *converted = new char[(line.size()+1)];
//The sentence is complete in this cout!
cout << line << " -printed string\n";
copy(line.begin(), line.end(), converted);
//sentence no longer complete!
cout << converted << " -printed char array\n";
我可能在前面的代码中有一些语法错误。因为我尝试了不同的方法,因此我擦除了代码,因此我从内存中执行此操作。关键是,使用.data(),copy()和.c_str()编译它们,并且都给出了相同的输出:
b 12 3 4 -printed string
b -printed char array
现在我完成了我的作业,显然这不是一个完整的第一个。我想我已经读过一些可能发生的事情,就是所有这些方法都将空格“”解释为“\ 0”,所以它在读完“b”后就会停止。修复它的方法之一是使用boost库。
不幸的是,这不是我的选择。我正在研究一种不能依赖外部库的可交付成果。一些帮助将非常感激。
提前致谢。
修改
代码:
(...)
if (fh.is_open()){
while (fh.good()){
getline(fh,line);
char *converted = new char[(line.size()+1)];
cout << line << " -printed string\n";
strcpy(converted, line.c_str());
cout << converted << " -printed char array\n";
(...)
答案 0 :(得分:2)
#1和#2中的错误,你必须复制字符,你所做的只是复制指针。
替换
converted = line.data();
converted[line.size()] = '\0';
与
strcpy(converted, line.c_str());
尝试#3更好但忘记添加空终止符。
也许你应该研究使用std :: string进行标记化的方法,然后你就不会把这一切搞得一团糟。
答案 1 :(得分:1)
现在指出了代码的问题
如果要将字符串(行)拆分为空格,则可能需要使用格式化输入而不是标记化。类似的东西(这没有经过测试)
#include <sstream>
#include <string>
while (std::getline(infile, line))
{
std::istringstream iss(line);
string token;
while(iss >> token) {
// Do your thing on token
}
}
根据您的需要进行修改。
答案 2 :(得分:0)
尝试#1中的问题例如:
内存泄漏:首先将指针设置为新分配的内存块,然后将指针重置为line.data()
未定义的行为:您不能修改std::string::data()
或std::string::c_str()
指向的指针所指向的内容。它可能是字符串对象保存的实际缓冲区的内部副本。
为了将字符串拆分为由空格分隔的部分,您可以尝试以下方法:
split(const std::string &line, char &letter, std::vector<double> &numbers) {
typedef std::string::size_t size_t;
size_t n = line.find(' ');
if (n == std::string::npos || n > 1) {
// there aren't any spaces or the first part contains
// more than one letter!
// bad case? throw something or return an error code
}
letter = line[0];
size_t n2 = line.find(' ', n);
while (n2 != std::string::npos) {
numbers.push_back(str2double(line.substr(n, n2 - n)));
n = n2;
n2 = line.find(' ', n);
}
}
我没有测试代码。可能是您必须将n + 1
写入find
的电话或类似的内容。你必须自己编写str2double
函数。