2011-12-23 75 views
0

当我在case 1(换句话说,在一个while循环后)呼叫case 2时,下面的代码会产生两个笑脸。然而printSentence();的工作原理应该是在case 1C控制台应用程序在循环后给出笑脸

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

    char *enterSentence(); 
    void printSentence(char *); 
    char *sentence; 
    int willContinue = 1; 

main() { 
    while (willContinue) { 
    int a; 
    scanf("%d", &a); 
    switch (a) { 
      case 1: 
       getchar(); 
       sentence = enterSentence(); 
       printSentence(sentence); 
       break; 
      case 2: 
       getchar(); 
       printSentence(sentence); 
       break; 
      case 3: 
       willContinue = 0; //exit 
       break; 
       } 
    } 
} 

char *enterSentence() { 
     char temp[999]; 
     gets(temp); 
     return temp; 
     } 

void printSentence(char *asd) { 
     puts(asd); 
     } 
. 
. //more code 
. 

我不知道什么是这里的问题,感谢您的帮助..

+0

'句子'在每个循环后似乎都不会被清除。 – Blender 2011-12-23 21:16:47

+1

哦!不要使用'gets()'。它不能安全使用,并已从最新的C标准(C11)中删除。 – pmg 2011-12-23 21:30:08

回答

5

temp当地的功能enterSentence。它在输入函数时创建,并在函数终止时被销毁。

当您返回对象的地址(return temp;)时,它仍然存在并具有该地址,但之后会立即销毁,并且调用函数会收到指向无效位置的指针。

快速和肮脏的解决方案:让temp静态对象,因为该方案开始,可以活到它结束

static char temp[999]; 

注:static是一个快速和肮脏的解决方案,正如我所说。它最好避免。


编辑

慢速和清洁的解决方案:temp对象移动到调用函数和它的指针传递给函数

int main(void) { 
    char temp[999]; 
    /* ... */ 
    enterSentence(temp, sizeof temp); 
    /* ... */ 
} 

size_t enterSentence(char *dst, size_t len) { 
    size_t retlen; 
    fgets(dst, len, stdin); 
    retlen = strlen(dst); 
    if (dst[retlen - 1] == '\n') dst[--retlen] = 0; 
    return retlen; 
} 
+0

非常丰富的答案。谢谢! – Ghokun 2011-12-23 21:27:14

0

存储在sentence先前值保持原样。