在C中的fgets()之后清除输入缓冲区

时间:2016-08-04 12:55:34

标签: c inputstream fgets fflush

#include <stdio.h>
int main()
{
  char name[10];
  for(int i=0;i<=10;i++)
  {
    printf("Who are you? ");
    if(fgets(name,10,stdin)!=NULL)
    printf("Glad to meet you, %s.\n",name);
  }
  return(0);
}

当我输入大于10个字符的内容时,循环会跳过。

Who are you? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaa

我想我想从剩余的字符中清除输入缓冲区。最好的方法是什么......?

4 个答案:

答案 0 :(得分:10)

检查name中是否存在换行符。

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

int main(void){
    char name[10];

    for(int i=0;i<=10;i++){
        printf("Who are you? ");
        if(fgets(name,10,stdin)){
            char *p;
            if(p=strchr(name, '\n')){//check exist newline
                *p = 0;
            } else {
                scanf("%*[^\n]");scanf("%*c");//clear upto newline
            }
            printf("Glad to meet you, %s.\n", name);
        }
    }
    return(0);//Parentheses is not necessary
}

答案 1 :(得分:2)

检查'\n'是否获得'\n'。如果没有 printf("Who are you? "); if (fgets(name, 10, stdin) != NULL) { if (!strchr(name, '\n')) { // consume rest of chars up to '\n' int ch; while (((ch = getchar()) != EOF) && (ch != '\n')) /* void */; if (ch == EOF) /* input error */; printf("Glad to meet you, %s.\n", name); } else { printf("Glad to meet you, %s.", name); // name includes ENTER } } ,则当前行中的某些字符尚未被读取。你可以简单地忽略它们。

<?php
// src/AppBundle/DataFixtures/ORM/LoadCourseData.php

namespace AppBundle\DataFixtures\ORM;

use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
use AppBundle\Entity\Course;

class LoadCourseData extends AbstractFixture implements OrderedFixtureInterface
{
    public function load(ObjectManager $manager)
    {
        $course = new Course();
        $course->setName('How to make data fixtures in Symfony lol')
            ->setAuthor($this->getReference('admin-user'))
            ->setSummary('You\'ll know when I know!')
            ->setLicense($this->getReference('cc-by'))
            ->setDifficulty(1);

        // Persist to generate slug (to be used for uploads)
        $manager->persist($course);

        // Attach file

        // I copy it to a temporary directory as per the Symfony2 answer
        copy(__DIR__.'/../Files/kitten.jpg', '/tmp/kitten.jpg');

        // These are filled in for completeness
        $mimetype = MimeTypeGuesser::getInstance()->guess('/tmp/kitten.jpg');
        $size     = filesize('/tmp/kitten.jpg');

        // Create a new UploadedFile
        $file = new UploadedFile('/tmp/kitten.jpg', 'kitten.jpg', $mimetype, $size, null, true);

        // I have to move it manually?
        // Plus how can I take advantage of the VichUploader namer?
        $file->move(__DIR__.'/../../../../web/img/upload/course/');

        // Apply to entity
        $course->setImageFile($file);

        // Persist
        $manager->persist($course);
        $manager->flush();
    }

    public function getOrder()
    {
        return 4;
    }
}

答案 2 :(得分:1)

来自fgets的文件(强调我的):

  

从流中读取字符并将它们作为C字符串存储到str中   直到(num-1)个字符被读取或者是换行符或者   达到了文件结尾,以先发生者为准

所以你的输入(超过缓冲区)是以9个字符的块(+1空终止字符)读取的。

您需要反复调用fgets,直到最后一个读取字符为换行符(\ n)。

答案 3 :(得分:1)

您需要使用以下内容查找\n

/* flush unread input buffer */
while( ! strchr( name, '\n' ) )
    if( ! fgets(name,(sizeof name),stdin) )
        break;

注意:不确定您是将其视为错误还是功能,但短名称将包含最终的\n。这导致类似:

Glad to meet you SSS
.