Я пытаюсь создать обратную строку, используя getchar (), чтобы сначала прочитать строку в формате массива. Я еще не написал реверсивную часть. Код работает для любых строк без пробелов. Ex . "Привет мир!" выведет "HelloWorld!" но "Привет, мир!" будет только выводить "Привет".

#include <stdio.h>

#define MAX_SIZE 100

int main() 
{
    char temp;
    char my_strg[MAX_SIZE];
    int length;

    printf("Please insert the string you want to reverse: ");
    scanf("%s", my_strg);

    while((temp = getchar()) != '\n')
    {
        my_strg[length] = temp;
        length++;
    } 

    printf("%s\n", my_strg);

    return 0;
}
0
Jeremy Eisner 28 Янв 2020 в 18:39

3 ответа

Лучший ответ

Ваша программа имеет неопределенное поведение , так как вы пытаетесь получить доступ к элементу массива, my_strg[length] со значением unitialized length.

Чтобы это исправить, переместите объявление length в после вызова scanf и инициализируйте его длиной строки, которую scanf читает:

scanf("%s", my_strg);
size_t length = strlen(my_strg);

Также можно полностью удалить вызов scanf и инициализировать length до нуля:

    char my_strg[MAX_SIZE] = { 0, }; // Note: make sure you ALSO initialize your array!!
    printf("Please insert the string you want to reverse: ");
    size_t length = 0;
    while ((temp = getchar()) != '\n') {
    //..

Примечание. Если вы (по какой-то причине) не хотите инициализировать весь массив в нули (как будет делать первая строка в моем втором блоке кода), то обязательно добавьте нулевой (nul) символ в конец строки, прежде чем печатать ее (или делать что-либо еще с ней). Вы можете просто добавить эту строку после цикла while:

    my_strg[length] = '\0'; // "length" will already point to one-beyond-the-end

РЕДАКТИРОВАТЬ: Чтобы рассмотреть очень хорошие замечания, высказанные Дэвидом К. Ранкином в разделе комментариев, вы можете ( должен) улучшить управление циклом while, чтобы: (а) предотвратить переполнение буфера и (б) обработать условия ошибки ввода Что-то вроде этого:

while ((length < MAXSIZE - 1) && (temp = getchar()) != '\n' && temp != EOF) {
    //..

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

2
Adrian Mole 28 Янв 2020 в 16:38

Ваша проблема scanf. scanf читает только до тех пор, пока не встретятся пробелы. Чтобы это исправить, вы можете использовать fgetsstrcspn для удаления новой строки):

if(fgets(my_strg, sizeof(my_strg), stdin) == NULL)
{
    perror("fgets");
    return EXIT_FAILURE;
}
my_strg[strcspn(my_strg, "\n")] = '\0';

Или с scanf ...

if(scanf("%99[^\n]", my_strg) != 1)
{
    fprintf(stderr, "scanf() failed to read\n");
    return EXIT_FAILURE;
}

После этих изменений вы можете полностью удалить цикл getchar.

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

Бонус: вот как перевернуть строку:

size_t l = strlen(my_strg) / 2;
char *s = my_strg, *e = s + l;
while(l--)
{
    char tmp = *--e;
    *e = *s;
    *s++ = tmp;
}
2
S.S. Anne 28 Янв 2020 в 16:44

По определению scanf("%s", my_strg) читает строку до первого пробела (и пробел считается как пробел). Поэтому "Hello world" будет читаться до первого пробела, то есть my_strg будет содержать "Hello". Чтобы читать до новой строки (включая новую), используйте fgets.

Кстати: переменная length неинициализирована, так что вы получаете неопределенное поведение.

1
Stephan Lechner 28 Янв 2020 в 15:44