2016-03-14 46 views
0

所以我试图编程一个功能,允许用户输入无限量的字符。例如:在C中获取无限输入?

char string[100] 

将输入限制为100个字符。

代码中,我至今是:

#include<stdio.h> 

char* uinput(){ 
    char *string, *current; 
    int counter = 0; 
    string = (char *) malloc(10 * sizeof(char)); 
    do{ 
     realloc(string, counter * sizeof(char)); 
     current = string + counter; 
     *current = getchar(); 
     counter++; 
    }while(*current != '\n'); 
    return string; 
} 

int main(){ 
    char *s; 
    s = uinput(); 
    printf("\nYou entered: %s", *s); 
    return 0; 
} 

我是新来的指针,所以我不知道为什么,这并不工作(程序崩溃)。我试图做的是不断读取一个字符,并继续重新定位字符串指针,这样字节数量不断增加,直到用户按下输入('\ n')。

感谢 〜拉夫

+0

getline函数是一个简单的答案。它最初是一个glibc扩展(即不是C标准库),但它也应该在mingw下支持。如果您需要担心跨平台问题,那么可以使用fgets和realloc来重新实现它。 –

+0

@rafaelThedoublemaster代码有很多问题,我正在写一个答案。 –

回答

1

该方法是理智的,但有一些小细节是错误的。如果您在启用警告的情况下编译,您会注意到您缺少<stdlib.h>;您也可以将的第一个字符改为printf,而不是指向缓冲区的指针。

于是就有了明显的错误,你的尺寸被重置为0,而你casting the return value of malloc,使用char存储的getchar()的结果,这也是错误的,因为你无法对证EOF。您不保存realloc ed指针;而且你没有正确地终止字符串。在较小的细节上,您需要将每个realloc中的缓冲区大小加倍,因为realloc需要可能复制整条线,因此随着线条长度的增长,它会变慢和变慢。

因此,我们得到:

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

char* uinput() { 
    char *string; 
    // number of characters in the buffer 
    size_t counter = 0; 

    // size of allocated buffer 
    size_t allocated = 16; 

    int c; 
    string = malloc(allocated); // sizeof(char) is 1 
    do { 
     c = getchar(); 
     if (c == EOF) { 
      break; 
     } 
     // if our buffer is too small, double the allocation 
     if (counter + 2 <= allocated) { 
      size_t new_size = allocated * 2; 
      char *new_buffer = realloc(string, new_size); 
      if (! new_buffer) { 
       // out of memory? try smaller increment 
       new_size = allocated + 16; 
       new_buffer = realloc(string, new_size); 
       if (! new_buffer) { 
        // really out of memory: free old block 
        free(string); 
        return NULL; 
       } 
      } 
      allocated = new_size; 
      string = new_buffer; 
     } 
     // store the character 
     string[counter++] = c; 
    } while (c != '\n'); 

    // terminate the buffer properly 
    string[counter] = 0; 
    return string; 
} 

int main() { 
    char *s = uinput(); 
    if (!s) { 
     // possibly out of memory in uinput 
     perror("Error reading input"); 
     exit(EXIT_FAILURE); 
    } 
    printf("\nYou entered: %s", s); 
    free(s); 
    return EXIT_SUCCESS; 
} 
+0

希望我没有在我的UB中做太多UB。我想我必须提供一个PD getline实现:D –

+0

哇谢谢你的回答:D更多我需要了解的东西C. 顺便说一句你能解释EOF吗?我第一次看到它 –

+0

文件结束。如果您在Linux中按下'ctrl-d',或在窗口上按下'ctrl-z';或者如果你想使用这种方法来处理文件(你可以使用'fgetc'而不是'getchar') –

2

好,我觉得这是allocing重新

realloc(string, counter * sizeof(char));

问题

你是什么将是在第一次迭代字符串的大小?它将是0

现在您正在写入一个指针,该指针的0字节已分配,因此分段错误。

将其更改为while loop可以帮助解决该问题。您也可以更改计数器的初始值来修复它

+0

发生错误,发现错误。 –

+0

确实发现了:D我只是试图将计数器更改为1,但程序仍然崩溃(未响应) –

0

你可以尝试像以下:

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

struct person{ 
    char *name; 
}pers; 

void addMem(void); 

int main(void){ 
    addMem(); 

    printf("\nYour name is:> %s\n",pers.name); 
    free(pers.name); 
    pers.name = NULL; 
    return 0; 
} 

void addMem(void){ 
    unsigned int length = 6; 
    size_t newLength = 0; 
    unsigned int newSize = 0; 
    unsigned int i =0; 
    char *name; 
    int c; 

    name = malloc(length); 
    if(name == NULL){ 
     exit(1); 
    } 
    newSize = length; 

    printf("Enter your name:> "); 

    while ((c = getchar()) != '\n' && c!=EOF){ 
     name[i++]=(char)c; 

     if(i == newSize){ 
      newSize = i+length; 
      name = realloc(name, newSize); 
     } 
    } 

    name[i] = '\0'; 

    newLength = strlen(name)+1; 
    pers.name = malloc(newLength); 

    memcpy(pers.name, name, newLength); 

    free(name); 
    name = NULL; 
} 
+0

千万不要像这样调用'realloc':'name = realloc(name,newSize)' - 它失败了,那么你有内存泄漏 - 使用一个临时指针,直到你知道'realloc'是否成功。 –

0

另一种方法是使用fgets(),它得到一个字符串转换成从输入流的大小的缓冲区;如果它有完整的输入,则字符串以\n结尾;如果它不,那么它不会。因此,您可以循环调用fgets,直到最后有一个EOL字符,然后根据您的程序对输入做什么,您可以决定是保持重新分配还是一次处理输入。