0

正如标题所建议的,我在将字符串转换为 char 数组时遇到了一些麻烦。

首先让我明确我需要这样做的原因,因为如果我的方法是错误的,我很乐意采取不同的方式。(虽然我更喜欢答案可以直接关注手头的问题)

我有一个包含几行的文件。每行都有格式

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 复制()

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 打印字符串

b -打印的字符数组

现在我已经完成了我的作业,显然这不是一个完整的第一次。我想我在某处读到过,可能发生的事情是所有这些方法都将空白空间“”解释为“\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";
(...)
4

3 回答 3

2

#1和#2中的同样错误,您必须复制字符,您所做的就是复制指针。

代替

converted = line.data();
converted[line.size()] = '\0';

strcpy(converted, line.c_str());

尝试 #3 更好,但忘记添加空终止符。

也许您应该研究使用 std::string 进行标记化的方法,那么您就不会搞砸了。

于 2013-03-24T11:37:14.510 回答
1

现在已经指出了您的代码的问题

如果您打算用空格分割字符串(行),那么您可能想要使用格式化输入而不是标记化。类似的东西(这未经测试)

#include <sstream>
#include <string>
while (std::getline(infile, line))
{
    std::istringstream iss(line);
    string token;
    while(iss >> token) { 

       // Do your thing on token

    }
}

根据您的需要对其进行修改。

于 2013-03-24T12:36:29.987 回答
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函数。

于 2013-03-24T12:36:39.670 回答