字符* 到字符串 c++(结果不是预期的)

Char* to string c++ (result not expected)

本文关键字:结果 字符串 c++ 字符      更新时间:2023-10-16

我已经花了 4 个小时试图解决这个问题,但我不能。我有这个功能:

  string getRuta(int i, char* buffer, string directorio) {
    int j = 0;
    string nom;
    char s;
    do {
            s = (char) buffer[i];
            nom[j] = s;
            j++;
            i++;
    } while (buffer[i] != 13);
    nom[j] = '';
    char *cstr = new char();
    strcpy(cstr, directorio.c_str());
    strcat(cstr, nom.c_str());
    printf("%sn",cstr);
    string ruta = cstr;
    printf("%sn",ruta.c_str());
    return ruta; }

我不明白为什么,但是在第一次打印时我得到了预期的输出,但第二次打印了一些奇怪的东西。我给你函数输入,打印结果。

缓冲区 = "共享 FEO"directorio = "/home/demian/archredes/"首次打印:/home/demian/archredes/feo第二次打印:/home/demian/archredes/fA

谢谢!

你通过修改std::string末尾的字符(两行nom[j] =行)来调用未定义的行为。应改用其 push_back 成员函数,并直接连接字符串,而不是使用 char 缓冲区。

此外,您只分配一个字符,然后strcpy过去...并泄漏其指针。

此外,您使用幻数而不是字符常量 r

这是一个更正(并且更简单)的版本:

string getRuta(int i, char const* buffer, string directorio) {
    string nom;
    char c;
    do {
        c = buffer[i];
        nom.push_back(c);
        i++;
    } while (buffer[i] != 'r');
    string ruta = directorio + nom;
    printf("%sn",ruta.c_str());
    return ruta;
}

您似乎在变量 cstr 中为整个字符串分配了 1 个字节的内存。尝试:

char *cstr = new char [directorio.size() + nom.size() + 1];

这种方式混合C和C++并不是明智之举。如果您正在编写C++代码,请尽可能避免使用 C 样式的代码。现在在此代码中:

char *cstr = new char();
strcpy(cstr, directorio.c_str());
strcat(cstr, nom.c_str());

cstr 是指向 1 char 的指针。您可能的意思是分配一个数组:

char *cstr = new char[directorio.size() + nom.size() - 1];

然而,您正在使用std::string对象,因此您实际应该做的是:

std::string ruta = directorio + nom;

您需要分配完整的字符数组而不是单个字符。照原样,您正在使用 strcpy 损坏内存,因为您分配了 1 个字符,然后将更多的数据复制到该空间中。

太多的代码和糟糕的 C/C++ 字符串组合。

简短版本:

// Precondition: i is a valid index into the buffer.
// Use a const char* (please)
// Use std::size_t (maybe)
string getRuta(std::size_t i, const char* buffer, string directorio) {
    std::size_t k = i;
    // Test for end of string and 'r' == 13
    while(buffer[k] && buffer[k] != 'r') ++k;
    // Append the whole range once, to reduce the number of 
    // possible reallocations:
    return directorio.append(buffer + i, k - i);
}
int main()
{
    const char* buffer = " Worldrn Planet";
    std::cout << getRuta(0, buffer, "Hello") << std::endl;
    return 0;
}