Печать строки в C с использованием функции - PullRequest
0 голосов
/ 25 сентября 2010

Я новичок в C и пытаюсь узнать, как взять строку и напечатать ее с помощью функции.Я везде вижу примеры использования while(ch = getchar(), ch >= 0), но как только я помещаю его в функцию (вместо main ()), она перестает работать.Прямо сейчас он застрял в бесконечном цикле ... почему это так?

// from main():
// printString("hello");

void printString(char *ch)
{
    while (*ch = getchar(), *ch >= 0)
    putchar(*ch);
}

Ответы [ 4 ]

3 голосов
/ 25 сентября 2010

Что происходит здесь следующее:

  1. в функции main вы вызываете printString с указателем на строку "привет"
  2. функция printString пытается прочитать символ с getchar()
  3. и сохраните этот символ вместо 'h'

Правила языка гласят, что попытка изменить это «h» - это неопределенное поведение. Если вам повезет, ваша программа вылетает; если вам не повезло, программа будет работать.

Вкратце: getchar() используется для чтения; putchar() используется для письма.

И вы хотите написать 5 букв: 'h', 'e', ​​'l', 'o' и другое 'o'.

    hello
    ^            ch is a pointer
    ch           *ch is 'h' -- ch points to an 'h'

Есть ли что-то после этого последнего 'o'? Есть! A '\0'. Нулевой байт завершает строку. Так что попробуйте это (с printString("hello");) ...

void printString(char *ch)
{
    putchar(*ch); /* print 'h' */
    ch = ch + 1;  /* point to the next letter. */
                  /* Note we're changing the pointer, */
                  /* not what it points to: ch now points to the 'e' */
    putchar(*ch); /* print 'e' */
    ch = ch + 1;  /* point to the next letter. */
    putchar(*ch); /* print 'l' */
    ch = ch + 1;  /* point to the next letter. */
    putchar(*ch); /* print 'l' */
    ch = ch + 1;  /* point to the next letter. */
    putchar(*ch); /* print 'o' */
    ch = ch + 1;  /* point to the next letter. What next letter? The '\0'! */
}

Или вы можете написать это в цикле (и вызвать из main с разными аргументами) ...

void printString(char *ch)
{
    while (*ch != '\0')
    {
        putchar(*ch); /* print letter */
        ch = ch + 1;  /* point to the next letter. */
    }
}
3 голосов
/ 25 сентября 2010

getchar() читает пользовательский ввод из стандартного ввода.Если вы хотите напечатать передаваемую строку, вам не нужно getchar().

Давайте рассмотрим шаг за шагом.Цикл, который вы читаете, один символ за раз от стандартного до тех пор, пока не достигнет конца файла.Вот что проверяет ch >= 0 тест: продолжайте читать, пока мы получаем правильные символы.Для печати символов строки условие изменяется.Теперь действительный символ - это все, что не NUL ('\0').Поэтому мы изменим условие цикла на:

while (*ch != '\0')

Далее выясним тело цикла.putchar(*ch) в порядке;мы оставим это там.Но без getchar() мы должны выяснить, что эквивалентно выражению «получить следующий символ».

Это было бы ch++.Это продвигает указатель ch на следующий символ в строке.Если мы поместим это в конец цикла, то напечатаем символ, добавляем один пробел и проверяем, не является ли следующий символ ненулевым.Если это так, то мы распечатываем его, проверяем и проверяем.

while (*ch != '\0') {
    putchar(*ch);
    ch++;
}
2 голосов
/ 25 сентября 2010

Исходя из вашего описания, вы просто хотите:

void printString(char *ch)
{
  while(*ch) {
     putchar(*ch);
     ch++;
  }
}

Ваша оригинальная функция:

void printString(char *ch)
{
    while (*ch = getchar(), *ch >= 0)
    putchar(*ch);
}

Делает много вещей:

  1. читает символы из stdin
  2. сохраняет символ, прочитанный со стандартного ввода в первый символ, на который указывает ch (это может даже не сработать, если вы передадите строковый литерал.
  3. записывает символы в стандартный вывод.
  4. Завершается, когда символ чтения <0 (это не будет работать на некоторых платформах. Поскольку результат хранится в символе, вы не можете различить EOF и действительный символ. Ch должно быть int, как getchar ( ) возвращает int, чтобы вы могли проверить EOF) </li>
0 голосов
/ 25 сентября 2010

Я бы просто сделал printf("%s",str); или puts(str);

...