Различные результаты с использованием% c и цикла по сравнению с% s в printf со строкой, заканчивающейся нулем - PullRequest
1 голос
/ 14 января 2011

У меня есть переменная 'jmp_code', которая объявлена ​​как char *. Когда я запускаю следующие команды

printf("char by char, the code is '%c%c%c%c'\n", *jmp_code, *(jmp_code+1), *(jmp_code+2),*(jmp_code+3));
printf("printing the string, the code is '%s'\n", jmp_code);

Я получаю следующие результаты

char by char, the code is '0,0,0, ,'
printing the string, the code is 'ö\├w≡F┴w'

Я использую кодовые блоки. Вот пример кода, с которым я играю.

#include <stdio.h>
#include <string.h>

char * some_func(char * code);

char * some_func(char * code) {

    char char_array[4];

    strcpy(char_array, "000");

    code = char_array;

    return code;

}
int main ( void ) {

    char * jmp_code = NULL;

    jmp_code = some_func(jmp_code);

    printf("char by char, the code is '%c,%c,%c,%c,'\n", *jmp_code, *(jmp_code+1), *(jmp_code+2),*(jmp_code+3));
    printf("printing the string, the code is '%s'\n", jmp_code);

    return 0;

}

Я очень смущен этим. Любая помощь будет оценена.

Спасибо

Ответы [ 5 ]

4 голосов
/ 14 января 2011

Несколько быстрых наблюдений:

char * some_func(char * code) {
    char char_array[4];
    strcpy(char_array, "000");
    code = char_array;
    return code;
}

Вы не можете назначать строки, используя = в C. Это портит все - вы назначаете code указатель вашего локально выделенного char_array для кода, но вы не копируете содержимое памяти.Также обратите внимание, что поскольку char_array размещено в стеке (обычно), вы обнаружите, что оно исчезает, когда вы возвращаетесь из этой функции.Вы могли бы обойти это с помощью ключевого слова static, но я не думаю, что это самое хорошее решение здесь.Вы должны использовать что-то вроде ( большое предупреждение, этот пример не очень безопасен, вам нужно проверить длины строк, но для краткости ):

void some_func(char * code) {
    strcpy(code, "000");
    return;
}

(Обратитесь к this this ) для получения рекомендаций по безопасной обработке строки).

И позвоните по номеру some_func(jmp_code) в main.Если вы не уверены, что это делает, прочтите указатели .

Вторая проблема.

char * jmp_code = NULL;

В настоящее время вы объявили достаточно места для указателя на тип символа.Если вы хотите использовать мое предложение выше, вам нужно либо использовать malloc() и free(), либо объявить char jmp_code[4] вместо этого, чтобы было выделено место.

Что я думаю, что происходит?Ну, в моей системе я получаю:

и код '0,0,0 ,,' и код ''

Но ядумаю, что есть вероятность, что jmp_code указывает на нули в стеке, предоставляемые вашей some_func функцией.Я думаю, что в вашей системе данные были перезаписаны.

Вместо этого вы читаете информацию, которую ваш терминал интерпретирует как указанный символ.Прочитайте кодировку символов.Я особенно рекомендую начинать с Абсолютный минимум для каждого разработчика программного обеспечения. Абсолютно, положительно необходимо знать о Unicode и наборах символов (никаких оправданий!)

2 голосов
/ 14 января 2011

Вы печатаете с неверного указателя. char_array находится в стеке функции some_func ().
Функция возвращает указатель на то, что находится в стеке и не будет больше после того, как функция вернет!
Первый printf находит стек все еще без изменений, второй, возможно, обнаружил, что он заполнен ... мусором!

2 голосов
/ 14 января 2011

Может быть интересно посмотреть:

const char *pos = jmp_code;
while (*pos)
    printf("%d ", *pos++);
2 голосов
/ 14 января 2011

Вы возвращаете ссылку на временный массив. char_array уходит, когда some_func() возвращается, но вы продолжаете использовать его адрес. Вам нужно использовать malloc() для выделения массива, а затем free() после его использования.

1 голос
/ 14 января 2011

Я думаю, что char type не может использовать non-ascii char code.Это означает, что ваша строка содержит символы UTF-8 или подобные символы, код которых может находиться в диапазоне (0, более 9000) , а коды символов могут находиться в диапазоне (0, 255) .

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