如何实现获得()或与fgets(),而使用结构指针? [英] How to implement gets() or fgets() while using structure pointer?

查看:204
本文介绍了如何实现获得()或与fgets(),而使用结构指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面code与运行完全scanf()的,但我想输入的字符与空格一起。我曾尝试获得()与fgets()(以下注释),但它不工作(其跳到下一个迭代中环路放大器;由使用名称输入输出与fgets期间显示空(NULL)())。任何想法,该怎么办呢?

PS:我试过的fputs()与示例程序,其工作的罚款。但我在使用结构指针有点糊涂了。

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
结构细节{
    UINT标识;
    CHAR名称[20];
};诠释主(){
    INT TOT,我;
    结构细节*信息;
    的printf(被存储=输入没有细节。);
    scanf函数(%d个,&安培; TOT);
    信息=(结构详情*)的malloc(TOT *的sizeof(结构信息));    对于(i = 0; I< TOT,我++){
        的printf(%d个)ID为我+ 1);
        scanf函数(%d个,&安培;信息 - > ID);
        的printf(%d)NAME =,I + 1);
        与fgets(信息 - >姓名,20,标准输入); //如何使与fgets()的工作?
        // scanf函数(%S,&安培;信息 - >姓名); //正常工作与scanf()的
        信息++;
    }    对于(i = 0; I< TOT,我++){
     - 信息;
    }    的printf(\\ nDisplaying详细信息:\\ n);
    对于(i = 0; I< TOT,我++){
        的printf(%d)n =%d个\\ N%D)名称=%S \\ n,I + 1,信息 - >身份证,I + 1,信息 - >姓名);
    信息++;
    }返回0;
}


  

输出:


  [XYZ @某某:温度] $ ./fgets_Struct
输入no。的细节将被存储= 2
1)n = 111
1)名称= 2)n = 222
2)名称=
显示详细信息:
1)n = 111
1)名称=2)n = 222
2)名称=
[XYZ @某某:温度] $


解决方案

这个问题来自于%Dscanf函数。它不消耗行结束,所以下一次读取将跨preT它作为一个空行。

信息分配是错误的了。什么是你应该使用分配的大小不是信息的大小,但的大小元素指向的由信息

 的printf(请输入没有被存储细节=);
scanf函数(%d个\\ n,&安培; TOT); //< - 必须在这里消耗行结束
信息=(结构详情*)的malloc(TOT *
   的sizeof(*资讯)); //< - 尖锐的物体,而不是指针的大小使用

另外,与你的信息修修补补指针是不必要的和危险的。结果
类似的东西会更简单和更安全

 为(i = 0; I< TOT,我++){
    的printf(%d个)ID为我+ 1);
    scanf函数(%d个\\ n,&安培;信息[I] .ID)); //< - 在当前信息记录存储输入
                                 //吃起来行结束
    的printf(%d)NAME =,I + 1);
    与fgets(资讯[I] .name和//< - 同上
          的sizeof(资讯[I] .Name点),//与fgets将保证没有缓冲区溢出
          标准输入);
}的printf(\\ nDisplaying详细信息:\\ n);
对于(i = 0; I< TOT,我++){
    的printf(%d)n =%d个\\ N%D)名称=%S \\ n,I + 1,信息[I] .ID,I + 1,信息[I] .Name点);

对于scanf函数/与fgets,你的情况(与给scanf函数%S格式),,他们都应该读取输入,直到输入新的一行,包含空格。

编辑:我说了什么在这里,抱歉和感谢chux指正

scanf函数(%S)确实会停在第一个空格。如果你想整条生产线,最简单的方法是使用与fgets。如果你真的想用scanf函数,你需要像语法%[^ \\ n]的%* C

要确保你的缓冲区不溢出如果用户键入超过20个字符,您可以


  • 使用%19 [^ \\ n]的%* C scanf函数格式(需要20字符为'\\ 0'终止),或

  • 使用与fgets 20缓冲区大小(与fgets 需要终止的照顾,将在最多读通过19个字符,以便能够不溢出)添加'\\ 0'。

当然,你应该使用的sizeof 来计算最大的缓冲区大小,比如像:

 与fgets(资讯[I] .name和的sizeof(资讯[I] .Name点),标准输入);

因此​​,你将不必修改这个值,如果你决定,例如,有你的缓冲区的大小变更为50个字符。

The below code runs perfectly with scanf(), but i want to input characters along with white space. I have tried gets() and fgets() (commented below), but its not working (its skipping to next iteration in the loop & displaying blank(NULL) during output for Name input used by fgets()). Any idea how to do it?

PS: I've tried fputs() with sample programs, its working fine. But i am little confused while using structure pointer.

#include <stdio.h>
#include <stdlib.h>
struct details {
    uint Id;
    char Name[20];
};

int main() {
    int tot, i;
    struct details *info;
    printf("Enter no. of details to be stored = ");
    scanf("%d", &tot);
    info = (struct details *)malloc(tot*sizeof(struct details));

    for(i=0; i<tot; i++) {
        printf("%d)Id = ", i+1);
        scanf("%d", &info->Id);
        printf("%d)Name = ", i+1);
        fgets(info->Name, 20, stdin); //How to make fgets() work??
        //scanf("%s", &info->Name); //works fine with scanf() 
        info++;
    }

    for(i=0; i<tot; i++) {
    --info;
    }

    printf("\nDisplaying details:\n");
    for(i=0; i<tot; i++) {
        printf("%d)Id = %d\n%d)Name = %s\n", i+1, info->Id, i+1, info->Name);
    info++;
    }

return 0;
}

output:

[xyz@xyz:Temp] $ ./fgets_Struct
Enter no. of details to be stored = 2
1)Id = 111
1)Name = 2)Id = 222
2)Name =
Displaying details:
1)Id = 111
1)Name =

2)Id = 222
2)Name =
[xyz@xyz:Temp] $

解决方案

The problem comes from the "%d" scanf. It does not consume the line terminator, so the next read will interpret it as an empty line.

Your info allocation is wrong too. What you should use to allocate the size is not the size of info, but the size of an element pointed to by info.

printf("Enter no. of details to be stored = ");
scanf("%d\n", &tot); // <-- must consume end of line here
info = (struct details *)malloc(tot*
   sizeof(*info)); // <-- use size of the pointed object, not the pointer

Also, tinkering with your info pointer is unnecessary and dangerous.
Something like that would be simpler and safer

for(i=0; i<tot; i++) {
    printf("%d)Id = ", i+1);
    scanf("%d\n", &info[i].Id)); // <-- store input in current info record
                                 // and eat up the line terminator
    printf("%d)Name = ", i+1);
    fgets(info[i].Name,          // <-- idem
          sizeof(info[i].Name),  // fgets will guarantee no buffer overflow
          stdin);
}

printf("\nDisplaying details:\n");
for(i=0; i<tot; i++) {
    printf("%d)Id = %d\n%d)Name = %s\n", i+1, info[i].Id, i+1, info[i].Name);

As for scanf / fgets, in your case (with "%s" format given to scanf), they should both read the input until a new line is entered, spaces included.

EDIT: I said something wrong here, sorry and thanks to chux for correcting me.

scanf ("%s") will indeed stop at the first white space. If you want the whole line, the easiest way is to use fgets. If you really want to use scanf, you'll need a syntax like "%[^\n]%*c".

To make sure your buffer does not overflow if the user types more than 20 characters, you can either

  • use "%19[^\n]%*c" as scanf format (20th character is needed for the '\0' terminator), or
  • use fgets with 20 passed as buffer size (fgets takes care of the terminator, it will read at most 19 characters to be able to add the '\0' without overflowing).

Of course you should use sizeof to compute max buffer size, like for instance:

fgets(info[i].Name, sizeof(info[i].Name), stdin);

Thus you won't have to modify the value if you decide, for instance, to have your buffer size changed to 50 characters.

这篇关于如何实现获得()或与fgets(),而使用结构指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆