2013-08-17 62 views
1
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

typedef char* string; 

int main(void) 
{ 
    char *names[6]; 
    int num_entries = 0,i=0,size=0; 
    string name = (string) malloc(sizeof(char) * 16); 

    printf("\nHow many names do you want to enter ? \n"); 
    scanf("%d",&num_entries); 

    for(i=0 ; i < num_entries ; i++) 
    { 
     printf("\nEnter a name : "); 
     gets(name); 
     size = strlen(name); 
     names[i] = (string) malloc(sizeof(char)*size + 1); 
     strcpy(names[i],name); 
    } 

    for(i=0 ; i < num_entries ; i++) 
     puts(names[i]); 

} 

第一次在这个程序中的字符串没有被读取周围循环的第一时间,但是能正常工作的所有后续调用,程序只需简单的接受N个字符串,存储和显示他们。但它执行n-1次。解决方案也可以随意指出指针,分配等方式中的任何错误,任何反馈都会被赞赏。字符串没有被读取周围

+2

'gets()'是邪恶的。考虑使用'fgets()'来代替。查看本页底部附近的BUGS部分:http://manpages.debian.net/cgi-bin/man.cgi?query=fgets&apropos=0&sektion=0&manpath=Debian+7.0+wheezy&format=html&locale=en – alk

+0

更改了获取()调用fgets(name,16,stdin)仍然是bug – rootavish

+0

@alk只是对改进做出评论,而不是提供对问题的回答。这就是为什么它是评论,而不是答案。 :)这是另一个评论:因为你总是设置它们,所以你的整数预初始化程序是多余的。 :) – lurker

回答

2

呼叫gets在循环之前丢弃scanf左边的新行。

或者更好的是,使用标准的解决方法丢弃未读输入:

int c; 
while ((c = getchar()) != '\n' && c != EOF); 
+0

'char c; \t \t while((c = getchar()!='\ n')&& c!= EOF) \t \t {name [i] = c; \t \t i ++; } \t \t name [i] ='\ 0'; “这样的事情? – rootavish

+1

@ superuser47,'getchar'返回一个'int',所以'int c'就像Anthony所说的那样。他的建议只是用它来吞噬字符,直到下一行换行。如果你想改变你的代码来使用它作为阅读'name'的机制,那么如果你对它有更多的问题,那么把它作为你的原始文章的编辑来展示是很好的。 – lurker

+0

超级用户,您误认了代码的意图。在scanf(“%d”,&num_entries);'之后并且在循环之前使用它 - 放弃换行符。 –

2

这里的问题,这是典型的scanf声明的是,当你进入它不使用换行符你想要的名字的数量并按下“输入”。

因此,换行符停留在标准输入缓冲区中,直到您执行下一次读取,在这种情况下,这是您尝试读取的第一个名称,因此您的名字只是“换行符”。为了解决这个问题,请使用getchar()来消化换行符,这样就不会再有这个问题了。

通常,根据经验法则,您几乎总是希望在scanf声明后使用getchar()或类似的语句来处理此问题。

我修改了下面的代码,对我来说工作正常。由于某些行不是必需的,我也清理了一下。

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

typedef char* string; 

int main(void) 
{ 
    string names[6]; 
    int num_entries=0, i=0; 
    string name = malloc(sizeof(char) * 16); 

    printf("\nHow many names do you want to enter ? \n"); 
    scanf("%d",&num_entries); 
    getchar(); 
    for(i=0 ; i < num_entries ; i++) 
    { 
     printf("\nEnter a name : "); 
     fgets(name,16,stdin); 
     names[i] = malloc(sizeof(char)*strlen(name) + 1); 
     strcpy(names[i],name); 
    } 

    for(i=0 ; i < num_entries ; i++) 
     puts(names[i]); 
return 0; 
} 
+0

既然你已经声明了一个字符串typedef,你可以使用'string names [6]'而不是'char * names [6]'。至于'fgets',它会阻止你对16个字符的有限字符串大小进行溢出。 – xt454

1

下面是带有所有建议的代码。请注意,Anthony Accioly因答案而获得奖励。

int main(void) 
{ 
    char *names[6]; 
    int num_entries = 0, i = 0, size = 0, c = 0; 
    string name = malloc(sizeof(char) * 16); 

    if (!name) 
    { 
     printf("Unable to allocate memory for name\n"); 
     return(1); 
    } 

    printf("\nHow many names do you want to enter ? \n"); 
    scanf("%d",&num_entries); 
    while ((c = getchar()) != '\n' && c != EOF); 

    for(i = 0 ; i < num_entries; i++) 
    { 
     printf("\nEnter a name : "); 
     gets(name); 
     size = strlen(name); 
     names[i] = (string) malloc(sizeof(char)*size + 1); 
     strcpy(names[i],name); 
    } 

    for(i=0 ; i < num_entries ; i++) 
     puts(names[i]); 

    return(0); 
} 
0

您还可以使用fflush(stdin);作为替代getchar()while(...)声明。

P.S .:我很抱歉在这里写下我的建议,因为我没有足够的评论声望。