读取c中的输入后如何清除缓冲区?

用户8863098
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void generarDimension(int, void **, int);
void reallocarDimensiones(int, void **, int);
void preguntarValor(int *);
char *generarCadena(char *);

typedef struct listaAlu{//this is a list of students
    char cedula[7];//this means id
    char *nombreApellido;//this means name and lastname
    short curso;//this means the year of the student in college/school
    unsigned short anho;//and this means year-E.g: 2017
};

int main(void){
    struct listaAlu *alu = NULL;
    int salir=1;
    char c;
    unsigned int cont = 0;
    unsigned int i;
    size_t size = 0;
    struct listaAlu *temp = NULL;
    while(salir!=0){//Condition until user press exit option
        printf("Agregar Alumno?Ingrese 1 para Agregar, y 0 para salir\n");//This means "Add student?Press 1 to add, and 0 to exit
        preguntarValor(&salir);//this verifies user input
        if(salir==1){//if user adds then it asks info of the student
            cont++;
            if ( NULL == ( temp = realloc ( alu, size + 2))) {//realloc for each character input and '\0'
                fprintf ( stderr, "realloc problem\n");
            }//this is for increasing the number of students
            alu = temp;
            printf("Ingrese Cedula:\n");//This means "Enter id"
            scanf("%s", &(alu+(size))->cedula);
            printf("Ingrese Nombre y Apellido:\n");//This means "Enter name and lastname"
            (alu+(size))->nombreApellido = generarCadena((alu+(size))->nombreApellido);
            printf("Ingrese Curso:\n");//This means enter college/school year
            scanf("%hd", &(alu+(size))->curso);
            printf("Ingrese Anho:\n");//and this means "Enter year"
            scanf("%hd", &(alu+(size))->anho);
            size++;
        }
    }
    for(i=0;i<cont;i++){
        printf("\tAlumno %d\n", i+1);
        printf("Nombre:\t%s\n", (alu+i)->nombreApellido);
        printf("Cedula:\t%s\n", (alu+i)->cedula);
        printf("Curso:\t%d\n", (alu+i)->curso);
        printf("Anho:\t%d\n", (alu+i)->anho);
    }//This prints Everything the user entered
    free(alu);
    return 0;
}//Sorry for writing my program entirely on the main >.<

void generarDimension(int bloques, void **ptr, int tamanho){
    void **ptrAux;
    *ptrAux = malloc(bloques * tamanho);
    if(*ptrAux==NULL){
        printf("No se pudo almacenar memoria\n");
    }else{
            *ptr = *ptrAux;
            free(ptrAux);
        }
}//this I didn't use, but it is for generating an array through a pointer
void reallocarDimensiones(int bloques, void **ptr, int tamanho){
    void **ptrAux;
    *ptrAux = realloc(*ptr,bloques * tamanho);
    if(*ptrAux==NULL){
        printf("No se pudo almacenar memoria\n");
    }else{
            *ptr = *ptrAux;
            free(ptrAux);
        }
}//This I didn't either, but it is for reallocating any given pointer

void preguntarValor(int *n){
    long entero, lector;
    *n=-2;
    do{
        printf("\nSi ingresa otro numero o caracter, vuelva a ingresar opcion\n");
        while(!scanf("%d", &entero)){
            while((lector=getchar()) !='\n' && lector !=EOF );
        }
        *n=entero;
    }while(*n>1 || *n<0);//You can change this parameters according to the numbers you want
}//This subrutine scans only integers between 1 and 0

char *generarCadena(char *scaneado){
    char *temp = NULL;
    int in = 0;
    size_t size = 0;

    while ( '\n' != ( in = getchar ( ))) {//loop until newline
        if ( NULL == ( temp = realloc ( scaneado, size + 2))) {//realloc for each character input and '\0'
            fprintf ( stderr, "realloc problem\n");
            return scaneado;
        }
        scaneado = temp;
        scaneado[size] = in;//set input
        scaneado[size + 1] = '\0';//terminate
        size++;
    }
    return scaneado;
}//This subrutine is for geting an input of chars of any given length

这是一个存储大学/学校学生列表的程序,我想知道如何改进此代码,但是在我要求用户输入字符串的部分中,在第二个中我无法输入任何内容。如果我尝试输入 2 个以上的学生,我的代码不会打印我输入的学生的所有信息

巴马克·谢米拉尼
struct listaAlu *temp = NULL;
temp = realloc ( alu, size + 2);//<- wrong size

realloc(alu, size + 2)将在第一次运行时只分配 2 个字节。但你需要的远不止这些。所需的总大小是数组中元素的数量乘以结构的大小。那是sizeof(struct listaAlu)大约 15 个字节。

realloc( alu, sizeof(struct listaAlu) * (size + 1) );

您不需要将大小增加2.

确保在正确的位置检查输入。scanf失败时清除输入

要获取名字和姓氏,您可以使用fgetsstrdup

没有与主要问题generarDimensionreallocarDimensiones你可能想把它们排除在外。

struct listaAlu{
    char cedula[7];//this means id
    char *nombreApellido;//this means name and lastname
    short curso;//this means the year of the student in college/school
    unsigned short anho;//and this means year-E.g: 2017
};

void clear()
{
    int c;
    while((c = getchar()) != '\n' && c != EOF);
}

int main(void)
{
    struct listaAlu *alu = NULL;
    size_t size = 0;
    while(1)
    {
        alu = realloc( alu, sizeof(struct listaAlu) * (size + 1) );
        if (!alu)
        {
            fprintf(stderr, "realloc problem\n");
            break;
        }

        char buf[256] = { 0 };

        printf("Enter id:\n");
        fgets(buf, sizeof(buf), stdin);
        buf[strcspn(buf, "\r\n")] = 0;
        buf[sizeof(alu[size].cedula) - 1] = 0;
        strcpy(alu[size].cedula, buf);

        printf("Enter name and lastname:\n");
        fgets(buf, sizeof(buf), stdin);
        buf[strcspn(buf, "\r\n")] = 0;
        alu[size].nombreApellido = _strdup(buf);

        for(;;)
        {
            printf("Enter college/school year:\n");
            if (scanf("%hd", &alu[size].curso) == 1)
                break;

            printf("input error\n");
            clear();
        }

        for(;;)
        {
            printf("Enter year:\n");
            if (scanf("%hd", &alu[size].anho) == 1)
                break;

            printf("input error\n");
            clear();
        }

        size++;

        printf("Press 1 to continue\n");
        char input;
        scanf(" %c", &input);
        if(input != '1')
            break;
        clear();
    }

    for(size_t i = 0; i < size; i++)
    {
        printf("Alumno %d\n", i);
        printf("Nombre:\t%s\n", alu[i].nombreApellido);
        printf("Cedula:\t%s\n", alu[i].cedula);
        printf("Curso:\t%hd\n", alu[i].curso);
        printf("Anho:\t%hd\n", alu[i].anho);
    }

    for(size_t i = 0; i < size; i++)
        free(alu[i].nombreApellido);
    free(alu);
    return 0;
}


编辑

realloc不需要包装在不同的函数中。但出于娱乐目的,您可以执行以下操作:

void* my_realloc1(void *ptr, int size)
{
    ptr = realloc(ptr, size);
    if (!ptr) printf("error\n");  
    return ptr;
}

//usage:
alu = my_realloc1(alu, sizeof(struct listaAlu) * (size + 1));
if (!alu) printf("error\n");  

my_realloc1将在这里工作,但没有任何收获。这只是额外的代码行。realloc直接使用并进行必要的错误处理更容易、更清晰

另一种方法是传递引用:

void my_realloc2(void **ptr, int size)
{
    *ptr = realloc(*ptr, size);
}

//usage: (*** Note the address `&` operator ***)
my_realloc2(&alu, sizeof(struct listaAlu) * (size + 1));
if (!alu) printf("error\n");

这将再次起作用,但它只会添加更多代码。

功能generarCadena好像还行。你可以简化如下:

char *my_getline()
{
    char *buf = NULL;
    int in = 0;
    size_t size = 0;
    while('\n' != (in = getchar()))
    {
        size++;
        buf = realloc(buf, size);
        buf[size - 1] = (char)in;
    }

    size++;
    buf = realloc(buf, size);
    buf[size - 1] = 0;

    return buf;
}

//usage:
printf("Enter name and lastname:\n");
alu[size].nombreApellido = my_getline();

scanf用于读取 6 个字符(因为大小cedula为 7)

printf("Enter 6 characters:\n");
scanf("%6s", alu[size].cedula);
alu[size].cedula[6] = '\0';
clear();

为安全起见,请确保输入为空终止,并清除缓冲区。

或者您可以fgets像我在示例中使用的那样使用。这将读取多达 256 个字符:

char buf[256];
fgets(buf, sizeof(buf), stdin);

fgets有时更容易,因为您不需要清除缓冲区。但是buf包括行尾字符\n\n在这种情况下您必须删除

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

scanf读取后输入缓冲区是否被清除?

来自分类Dev

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

来自分类Dev

在C中如何读取超出缓冲区末尾的内容?

来自分类Dev

在 C++ 中清除空输入缓冲区的安全操作

来自分类Dev

Python:清除标准输入缓冲区

来自分类Dev

在金属中如何清除深度缓冲区或模板缓冲区?

来自分类Dev

如何使用Directx读取hdmi输入帧缓冲区?

来自分类Dev

在C#中清除鼠标缓冲区

来自分类Dev

如何从bash清除konsole中的回滚缓冲区?

来自分类Dev

如何在到达缓冲区而不是缓冲区已满时读取缓冲区中的数据?

来自分类Dev

如何读取输入流缓冲区中存储的字符数

来自分类Dev

如何读取输入流缓冲区中存储的字符数

来自分类Dev

从 SuperpoweredAndroidAudioIO 输入读取缓冲区?

来自分类Dev

清除cout缓冲区(C ++)

来自分类Dev

如何清除ReplaySubject上的缓冲区?

来自分类Dev

如何清除Neovim缓冲区

来自分类Dev

Python中的Memset(),清除缓冲区

来自分类Dev

强制在scanf中清除缓冲区

来自分类Dev

Python中的Memset(),清除缓冲区

来自分类Dev

C ++读取缓冲区中的整个文件

来自分类Dev

读取C中缓冲区的特定部分

来自分类Dev

C recv()未在缓冲区中读取

来自分类Dev

如何从Rust 1.0中的缓冲区读取整数?

来自分类Dev

检查cin输入,清除输入缓冲区

来自分类Dev

我如何正确地从标准输入中读取带有缓冲区的输入而不会截断任何单词?

来自分类Dev

我如何正确地从标准输入中读取带有缓冲区的输入而不会截断任何单词?

来自分类Dev

确定C缓冲区中多个以空格分隔的输入

来自分类Dev

有哪些方法可以将stdout捕获到读取时自动清除的缓冲区中?

来自分类Dev

您将如何限制缓冲区大小并返回c ++中的缓冲区限制?

Related 相关文章

  1. 1

    scanf读取后输入缓冲区是否被清除?

  2. 2

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

  3. 3

    在C中如何读取超出缓冲区末尾的内容?

  4. 4

    在 C++ 中清除空输入缓冲区的安全操作

  5. 5

    Python:清除标准输入缓冲区

  6. 6

    在金属中如何清除深度缓冲区或模板缓冲区?

  7. 7

    如何使用Directx读取hdmi输入帧缓冲区?

  8. 8

    在C#中清除鼠标缓冲区

  9. 9

    如何从bash清除konsole中的回滚缓冲区?

  10. 10

    如何在到达缓冲区而不是缓冲区已满时读取缓冲区中的数据?

  11. 11

    如何读取输入流缓冲区中存储的字符数

  12. 12

    如何读取输入流缓冲区中存储的字符数

  13. 13

    从 SuperpoweredAndroidAudioIO 输入读取缓冲区?

  14. 14

    清除cout缓冲区(C ++)

  15. 15

    如何清除ReplaySubject上的缓冲区?

  16. 16

    如何清除Neovim缓冲区

  17. 17

    Python中的Memset(),清除缓冲区

  18. 18

    强制在scanf中清除缓冲区

  19. 19

    Python中的Memset(),清除缓冲区

  20. 20

    C ++读取缓冲区中的整个文件

  21. 21

    读取C中缓冲区的特定部分

  22. 22

    C recv()未在缓冲区中读取

  23. 23

    如何从Rust 1.0中的缓冲区读取整数?

  24. 24

    检查cin输入,清除输入缓冲区

  25. 25

    我如何正确地从标准输入中读取带有缓冲区的输入而不会截断任何单词?

  26. 26

    我如何正确地从标准输入中读取带有缓冲区的输入而不会截断任何单词?

  27. 27

    确定C缓冲区中多个以空格分隔的输入

  28. 28

    有哪些方法可以将stdout捕获到读取时自动清除的缓冲区中?

  29. 29

    您将如何限制缓冲区大小并返回c ++中的缓冲区限制?

热门标签

归档