Как напечатать элементы с помощью указателей - PullRequest
0 голосов
/ 06 апреля 2011

Привет,

Я некоторое время изучал C ++.Я сейчас получаю указатели.Но я создаю программу на C ++, которая будет запрашивать ввод строки ("% s").И я хочу отобразить его символ в другой строке.Но когда я запускаю программу, я получаю неправильные буквы.Вот мой код:

#include<stdio.h>
#include<stdlib.h>
main() {
char* name;
name = (char *)malloc(sizeof(char));
printf("Enter string: "); scanf("%s", name);
while(*name != '\0') {
printf("%c", name); *name++
}
}

Ваш ответ высоко ценится.

Ответы [ 4 ]

2 голосов
/ 06 апреля 2011

Во-первых, если вы собираетесь изучать C ++, вы должны научиться писать программы на C ++, а не программы на C.Вот ваша программа на идиоматическом C ++:

#include <iostream>
#include <string>
int main(int, char **) {
    std::string name;
    std::cout << "Enter string: " << std::flush;
    std::cin >> name;
    std::cout << name << "\n";
}

Одно из преимуществ использования C ++ и его стандартных библиотек над C и его стандартными библиотеками заключается именно в следующем: вам почти никогда не нужно использовать указатели.

Но, принимая вашу программу за то, что она того стоит, есть несколько проблем.Во-первых, в C ++, если вы хотите получить доступ к заголовочным файлам C, вы должны включить их с именами C ++:

#include <cstdio>
#include <cstdlib>

Далее, main требует правильной подписи:

int main(int, char**) {

Самое главное, вы не выделяете достаточно места для имени вашего пользователя:

name = (char *)malloc(A_BIG_ENOUGH_NUMBER);

Здесь вы должны выделить достаточно места, чтобы scanf() не записывал после конца вашего буфера.Но вы не можете знать, насколько он велик, пока не закончится scanf.Этот catch-22 является источником ошибок "переполнения буфера".Для вашей тестовой программы, так как вы управляете вводом, вероятно, можно просто выбрать число больше, чем любое имя, которое вы когда-либо будете вводить.В производственном коде вы НИКОГДА, НИКОГДА не должны использовать scanf таким образом.

name = (char *)mallocc(40);

Кстати, если вы компилируете это как код на C, вы никогда не должны приводить результат от malloc,Если вы компилируете это как код C ++, вы должны всегда приводить результат из malloc.

printf("%c", *name); name++

В этой строке отсутствует точка с запятой.Вы скомпилировали эту программу?В будущем, пожалуйста, отправляйте только тот код, который вы скомпилировали.Пожалуйста, используйте функции вырезания и вставки вашего компьютера, чтобы публиковать код, никогда не вводите код вручную.

В этой строке есть две другие проблемы.Во-первых, вы должны отменить защиту указателя name, чтобы получить доступ к данным, на которые он указывает.(Итак, *name вместо name.) Во-вторых, вам не нужно разыменовывать имя во втором операторе в этой строке, поскольку вы ничего не делаете с результирующими указанными данными.(Итак, name++ вместо *name++.)

Наконец, что самое важное, покупайте, читайте и учитесь на хорошей книге .

2 голосов
/ 06 апреля 2011

malloc(sizeof(char)) выделяет место для одного символа.Это, вероятно, не то, что вы хотите.Как отмечают комментарии ниже, разыменование в *name++ не имеет смысла.Это не вредит, но, возможно, указывает на то, что вы думаете о чем-то неправильно.name++ имеет тот же эффект.

0 голосов
/ 06 апреля 2011

Ваша программа, скорее всего, печатает ненужные файлы, потому что вы выделяете только один байт для вашего строкового буфера. Когда пользователь вводит строку, у вас будет неопределенное поведение, потому что scanf будет писать после конца name.

Вы должны выделить name так:

char *name = (char *)malloc(MAX_STRING_SIZE, sizeof(char));

Еще лучше использовать calloc вместо malloc. Определите MAX_STRING_SIZE как хотите. Разумный размер зависит от приложения. В вашем случае, если пользователи будут вводить короткие строки, возможно, разумный размер буфера составляет 64 байта, или, возможно, 80 или 100.

Кроме того, в цикле while вы можете увеличивать и разыменовывать указатель за один шаг, например:

printf("%c", *name++);

Если вам не нравится быть таким кратким, то вы можете разбить их на части, но вам не нужно разыменовывать указатель, чтобы увеличить его.

printf("%c", *name); name++;
0 голосов
/ 06 апреля 2011

Это не C ++, это C.

malloc(sizeof(char)) выделит хранилище для одного символа, надеюсь, вы хотели большего.

Также нет необходимости динамически размещать здесь. Попробуйте:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    char name[256];
    char *p = name;

    printf("Enter string: ");
    scanf("%s", name);

    while (*p != '\0') {
        printf("%c", *p);
        p++;
    }

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