Char имеет размер, отличный от строки - PullRequest
0 голосов
/ 04 ноября 2011

Я работал с программой, которая использует функцию для установки нового значения в реестре, я использовал const char * для получения значения. Однако размер значения составляет всего четыре байта. Я попытался использовать std::string в качестве параметра вместо этого, он не работал.
У меня есть небольшой пример, чтобы показать вам, о чем я говорю, и вместо того, чтобы решать мою проблему с помощью функции, я бы хотел узнать причину, по которой она это делает.

#include <iostream>


void test(const char * input)
{
    std::cout << input;
    std::cout << "\n" << sizeof("THIS IS A TEST") << "\n" << sizeof(input) << "\n";
    /* The code above prints out the  size of an explicit string (THIS IS A TEST), which is 15. */
    /* It then prints out the size of input, which is 4.*/

    int sum = 0;
    for(int i = 0; i < 15; i++) //Printed out each character, added the size of each to sum and printed it out.
    //The result was 15.
    {
        sum += sizeof(input[i]);
        std::cout << input[i];
    }
    std::cout << "\n" << sum;
}
int main(int argc, char * argv[])
{
    test("THIS IS A TEST");
    std::cin.get();
    return 0;
}

Output:
THIS IS A TEST
15
4
THIS IS A TEST
15

Как правильно получить строковые параметры? Должен ли я перебирать весь массив символов и печатать каждый из них в строку (значение в реестре составляло только первые четыре байта символа)? Или я могу вместо этого использовать std::string в качестве параметра?
Я не был уверен, что это ТАК материал, но я решил опубликовать здесь, так как считаю, что это один из моих лучших источников для программирования информации, связанной с.

Ответы [ 5 ]

3 голосов
/ 04 ноября 2011

sizeof(input) - это размер const char*. strlen(input) + 1

sizeof("THIS IS A TEST") - это размер const char[].sizeof дает размер массива при передаче типа массива, поэтому он равен 15.

Для std::string используйте length()

2 голосов
/ 04 ноября 2011

sizeof дает размер, основанный на типе , который вы задаете в качестве параметра.Если вы используете имя переменной, sizeof по-прежнему основывает свой результат только на типе этой переменной.В случае char *whatever он сообщает вам размер указателя на символ, не размер буфера с нулевым символом в конце, на который он указывает.Если вы хотите последнее, вы можете использовать strlen вместо этого.Обратите внимание, что strlen сообщает вам длину содержимого строки, не , включая завершающий '\0'.Таким образом, если (например) вы хотите выделить место для дублирования строки, вам нужно добавить 1 к результату, чтобы сообщить вам общее пространство, занимаемое строкой.

Да, как правило, в C ++вы обычно хотите использовать std::string вместо указателей на char.В этом случае вы можете использовать your_string.size() (или, что эквивалентно, your_string.length()).

1 голос
/ 04 ноября 2011

std::string - это объект C ++, который нельзя передать большинству API.Большинство API принимают char*, как вы заметили, что очень отличается от std::string.Однако, поскольку это является общей потребностью, std::string имеет функцию для этого: c_str.

std::string input;
const char* ptr = input.c_str();  //note, is const

В C ++ 11 теперь также безопасно делать это:

char* ptr = &input[0]; //nonconst

, и вы можете изменять символы, но размер является фиксированным, и указатель становится недействительным, если вы вызываете любой мутирующий член std::string.

Что касается кода, который вы разместили,"THIS IS A TEST" имеет тип const char[15] размером 15 байт.Однако char* input имеет тип char* (очевидно), который имеет размер 4 в вашей системе.(В других системах это могут быть и другие размеры)

Чтобы найти размер c-строки, на которую указывает указатель char*, вы можете вызвать strlen(...), если она заканчивается на NULL.Он вернет количество символов перед первым нулевым символом.

0 голосов
/ 04 ноября 2011

Проще говоря, размер const char *! = Размер const char [] (если они равны, это по совпадению). Первый является указателем. В случае вашей системы указатель имеет 4 байта НЕЗАВИСИМО от типа данных. Это может быть int, char, float, что угодно. Это потому, что указатель всегда является адресом памяти и является числовым. Распечатайте значение вашего указателя, и вы увидите, что это на самом деле 4 байта. const char [] теперь является самим массивом и будет возвращать длину массива при запросе.

0 голосов
/ 04 ноября 2011

Если реестр, о котором вы говорите, является реестром Windows, это может быть проблемой Unicode и ASCII.Современная Windows хранит почти все строки как Unicode, который использует 2 байта на символ.Если вы попытаетесь поместить строку Unicode в std :: string, это может привести к получению 0 (нуля), который в некоторых реализациях строковых классов рассматривается как «конец строки».std :: wstring (широкая строка) или вектор (тип широких символов).Они могут хранить строки из двухбайтовых символов.

sizeof () также не дает вам значения, которое, как вы думаете, оно вам дает.Ваша система, вероятно, работает под управлением 32-битной Windows - это значение «4» является размером указателя на первый символ этой строки.Если это не помогло, пожалуйста, опубликуйте конкретные результаты, которые появляются, когда вы используете std :: string или std :: wstring (более чем сказать, что это не работает).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...