Как читать и выводить ввод с пробелами и переводом строки - PullRequest
0 голосов
/ 08 ноября 2018

Я пытаюсь отсканировать многострочный вход в C и вывести его. Однако у меня проблемы с обработкой пробелов и символов новой строки. Если ввод:

Hello.
My name is John.
Pleased to meet you!

Я хочу вывести все три строки. Но мой вывод в итоге просто:

Hello.

Вот мой код:

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

int main() 
{
    char s[100];
    scanf("%[^\n]%*c", &s);
    printf(s);
    return 0;
}

1 Ответ

0 голосов
/ 08 ноября 2018

Гораздо проще в использовании fgets():

#include <stdio.h>

int main(void)
{
    char buffer[1000];
    while (fgets(buffer, sizeof(buffer), stdin) && buffer[0] != '\n') {
        printf("%s", buffer);
    }
}

Пустая строка (первый символ - новая строка) заканчивает ввод.


Если вам нужно сначала прочитать все вводные данные перед печатью результата, все становится немного сложнее:

#include <stddef.h>  // size_t
#include <stdlib.h>  // EXIT_FAILURE, realloc(), free()
#include <stdio.h>   // fgets(), puts()
#include <string.h>  // strlen(), strcpy()

int main(void)
{
    char buffer[1000];
    char *text = NULL;  // pointer to memory that will contain the whole text
    size_t total_length = 0;  // keep track of where to copy our buffer to

    while (fgets(buffer, sizeof(buffer), stdin) && buffer[0] != '\n') {
        size_t length = strlen(buffer);  // remember so we don't have to call
                                         // strlen() twice.
        // (re)allocate memory to copy the buffer to:
        char *new_text = realloc(text, total_length + length + 1); // + 1 for the
        if (!new_text) {  // if (re)allocation failed              terminating '\0'
            free(text);   // clean up our mess
            fputs("Not enough memory :(\n\n", stderr);                   
            return EXIT_FAILURE;
        }
        text = new_text;  // now its safe to discard the old pointer
        strcpy(text + total_length, buffer);  // strcpy instead of strcat so we don't
        total_length += length;               // have to care about uninitialized memory 
    }                                         // on the first pass *)

    puts(text);  // print all of it
    free(text);  // never forget
}

*), и это также более эффективно, поскольку strcat() должен будет найти конец text перед добавлением новой строки. Информация у нас уже есть.

...