2012-10-07 30 views
0

运行时,我知道这是可能的初始化字符*在用户输入

char text[A_BIG_NUMBER]; 
printf("Enter your name"); 
scanf("%s",text); 

但有没有办法做到这一点? (不使用字符数组作为备用)

char* text; 
printf("Enter your name"); 
scanf("%s",text); 

,而第一种方式是容易的,但如果A_BIG_NUMBER是不是大到足以容纳用户输入的话就会产生问题的代码的其余部分字符串,对其他如果我们使用大量的手,那么它会浪费内存!

感谢

编辑:对不起,我错了标签。我只问C。

+0

如果您可以假设POSIX,我建议'为ssize_t函数getline(字符** lineptr,为size_t * N,FILE *流); '。 –

回答

1

你当然可以使用动态分配的内存,而不是数组,但溢出的根本问题依然存在:

char *text = malloc(A_BIG_NUMBER*sizeof(char)); 
printf("Enter your name"); 
scanf("%s",text); 

你需要告诉scanf的空间是有限的,这样的:

char text[201]; 
printf("Enter your name"); 
scanf("%200s",text); 

注意text[201]有终止一个多余的字符空间:%200s限制输入200“实”字,所以你需要提供额外的char'\0'

+0

嗯动态分配摆脱阵列,但正如你所说,你仍然需要猜测A_BIG_NUMBER –

+0

@YogenderSingh另一方面,大数值的价值可以比使用堆栈分配大得多。 – dasblinkenlight

3

既然你说C++,答案是“是的,字符串”:

std::string name; 

std::cout << "Enter your name: "; 

if (!std::getline(std::cin, name)) { /* unexpected end of input */ } 

// now use "name" 

当你发现,你一般需要动态分配存储外部数据。 (您的代码是不是很普遍:你不能有非常大的自动阵列,以及固定尺寸的增加任意幻数和约束。)C++是封装动态分配和清理的细节完美的语言,所以您可以使用简单的自动变量为您完成所有工作。

如果你不喜欢iostreams,你可以建立你自己的超载bool getline(std::FILE *, std::string &),通过调用std::fgets+=循环提取一个完整的行。

+0

抱歉标签错误。我只想要C中的东西。对不起 –

+0

@YogenderSingh:我明白了。耻辱。这将是很好的知道。 –

1

字符*不用于存储用户输入的字符串分配内存,这是第二码不起作用的原因。

如果你担心内存使用/浪费,你可以克服使用特定程序栈/堆这些限制。

+0

意味着如果没有预先分配的缓冲区,就没有办法做到这一点? –

+0

不,C需要分配一些内存位置来存储字符串输入。 –

0

在循环中使用带有fgets()的小型(ish)缓冲区。在循环realloc()内的最终目的地。

/* UNTESTED */ 
char smallish[1000]; 
char *destin = NULL; 
size_t destin_size = 1; 
while (fgets(smallish, sizeof smallish, stdin)) { 
    destin_size += strlen(smallish); 
    char *tmp = realloc(destin, destin_size); 
    if (!tmp) /* deal with error */; 
    destin = tmp; 
    strcat(destin, smallish); 
    if (smallish[strlen(smallish) - 1] == '\n') break; 
} 
/* use destin */ 
free(destin); 
0

可以使用的getchar,这里是一个示例代码:

int size = 128; 
    char *s = (char*)malloc (size); 
    char c; 
    int i; 
    while ((c = getchar()) != '\n' && c != EOF) 
    { 
     s[i] = c; 
     ++i; 
     if (i == size) 
     { 
      size = size * 2; 
      char *tmp = realloc (s, size); 
      if (tmp != NULL) 
      s = tmp; 
      else ; // error, try with malloc and copy or exit or whatever you want 
     } 
    } 
    s[i] = 0; 
+0

如果'realloc'失败,'s = realloc(s,size);'失去对分配内存的引用。临时性更安全并检查'realloc'是否返回NULL。 –

+0

char * s =(char *)malloc(size);仍然预先分配了内存,并且只是用另一种方式来表示char s [128]; ! –

+0

@Yogender Singh,也许我误解了你,但是malloc在堆上分配内存,而s [128]被分配在堆栈上。这是完全不同的,在后面的情况下,你不能调用realloc(s,new_size)而不会破坏堆。 – tozka