getchar () не читает места при создании массива строк? - PullRequest
0 голосов
/ 28 января 2020

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

#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;
}

Ответы [ 3 ]

2 голосов
/ 28 января 2020

Ваша проблема 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 l oop.

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

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

size_t l = strlen(my_strg) / 2;
char *s = my_strg, *e = s + l;
while(l--)
{
    char tmp = *--e;
    *e = *s;
    *s++ = tmp;
}
2 голосов
/ 28 января 2020

Ваша программа имеет неопределенное поведение , так как вы пытаетесь получить доступ к элементу массива, my_strg[length] с унифицированным значением 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 l oop:

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

РЕДАКТИРОВАТЬ: Для решения очень хорошие замечания, сделанные Дэвид C. Rankin в разделе комментариев, вы могли (должны) улучшить свой while l oop элемент управления, чтобы: (a) предотвратить переполнение буфера и (b) обработать условия ошибки ввода. Примерно так:

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

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

1 голос
/ 28 января 2020

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

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

...