无法从“获取(*缓冲区)”获取Int

时间:2016-03-18 06:59:48

标签: c struct

所以我的导师让我为数据结构获取一个整数,但是我应该得到的两个int部分,是通过获取,我认为他意味着我使用gets(temp)//临时代表char temp [50]然后执行x = strlen(temp); 到目前为止,这是我的工作:

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

#define N 20

struct one
{
    int ak;
    char pin[N];    
};

struct two
{
    int data,mat[N];
    struct one melos,item;
};

int main(void)
{
    bool x=true;
    int i;
    char temp[N];
    struct one person;
    struct two memb;

    /*GETTING VARS*/
    gets(person.pin);
    gets(memb.item.pin);
    gets(memb.melos.pin);
    person.ak=(int)gets(temp); 
    memb.data=(int)gets(temp);  
    for(i=0;i<N;i++)
        scanf("%d",&memb.mat[i]);
    scanf("%d",&memb.melos.ak);
    scanf("%d",&memb.item.ak);

    putchar('\n');

    /*CHECKING VARS*/
    puts("Posting vars in Data Struct ""one"" \n");
    printf("%d\n",person.ak);
    puts(person.pin);
    puts("Posting vars in Data Struct ""two"" \n");
    printf("%d\n",memb.data);
    putchar('\n');
    for(i=0;i<N;i++)
        printf("%d\t",memb.mat[i]);
    printf("\n%d\n",memb.melos.ak);
    puts(memb.melos.pin);
    printf("%d\n",memb.item.ak);
    puts(memb.item.pin);
    puts("**********************\n---POST_END---");

    return 1;                   
}

2 个答案:

答案 0 :(得分:2)

gets()的返回值是成功时传递的缓冲区的指针,如果失败则返回NULL。这并不意味着读取整数。

另请注意,您不应使用gets(),这有不可避免的缓冲区溢出风险。

您必须将读取的字符串转换为整数。

试试这个:

#include<stdio.h>
#include<stdlib.h> /* for using atoi() */
#include<string.h>

#define N 20

/* read one line while checking the size read */
char* safer_gets(char* outbuf, size_t max){
    size_t idx = 0;
    int input;
    if(max == 0) return NULL;
    while(idx + 1 < max && (input = getchar()) != EOF && input != '\n'){
        outbuf[idx++] = input;
    }
    if (idx == 0 && input == EOF) return NULL;
    outbuf[idx] = '\0';
    return outbuf;
}

/* read one line and convert it to integer */
int get_int(void) {
    char temp[N];
    safer_gets(temp, sizeof(temp));
    return atoi(temp);
}

struct one
{
    int ak;
    char pin[N];
};

struct two
{
    int data,mat[N];
    struct one melos,item;
};

int main(void)
{
    int i;
    struct one person;
    struct two memb;

    /*GETTING VARS*/
    safer_gets(person.pin, sizeof(person.pin));
    safer_gets(memb.item.pin, sizeof(memb.item.pin));
    safer_gets(memb.melos.pin, sizeof(memb.melos.pin));
    person.ak=get_int();
    memb.data=get_int();

    /* latter part omitted */
}

答案 1 :(得分:0)

避免使用gets - 我很惊讶您的课程提到它,因为它已从所有最新的C语言规范中删除,现在已在C ++ 11中弃用。

但如果你必须......

http://www.cplusplus.com/reference/cstdio/gets/

long int getIntegerWithGetS() {

    char* end;
    char* buffer = calloc( 1024, sizeof(char) ); // 1024 bytes should be enough

    long int result;
    bool got_result_yet = false;
    while( !got_result_yet ) {
        gets( buffer ); // DANGER WILL ROBINSON
        result = strtol( buffer, &end, 10 );
        if( result == 0 ) {
            if( end != buffer ) {
                result = 0;
                got_result_yet = true;
            }
        } else {
            if( result != LONG_MAX && result != LONG_MIN && errno != ERANGE ) got_result_yet = true;
        }
    }

    free(buffer);

    return result;
}

请注意我是如何在循环中调用我的代码所以我们将一直持续到我们从用户那里获得有效输入。我开始调用gets(填充缓冲区),然后使用strtolbuffer中的人类可读文本转换为实际的计算机int值 - 请注意{ {1}}比strtol更强大,并使用atoi代替long int作为其声明的类型。然后代码检查int错误条件(如果用户在失败时函数返回strtol时键入"0")。

我不会立即返回,因为0必须在buffer之前执行离开作用域,否则该缓冲区将保持未分配并因此泄露。