繁体   English   中英

如何接受大小不确定的字符串输入?

[英]How can I accept string inputs of undetermined size?

所以这里有一些python vsC。

我只是用python编写了一个程序来进行计算,该函数接受所有数字作为字符串输入,这样就可以处理难以置信的巨大数字。

无论如何,在C中没有指定字符串长度的确切限制就可以做到这一点?

因此,在下面的基本转换器函数中,我的字符串限制为100个字符atm。 (当前仅转换为以10为基数)

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

char SYMBOLS[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };

//just testing how to access the SYMBOLS[]
int print_symbols() {


    printf("Printing individual characters at a time:\n");
    for (int i = 0; i < strlen(SYMBOLS); i++)
    {
        printf("%c ",SYMBOLS[i]);
    }
    printf("\nLength/num of symbols: %d", strlen(SYMBOLS));

    printf("\n\nPrinting the whole string at once:\n");
    printf("%s", SYMBOLS);
    printf("\n\n");

    return 0;
}

//accepts a string to display a prompt to the user and returns input
char* input(char prompt[]) {
    static char received[100];
    printf("%s", prompt);
    fgets(received,100,stdin);
    //Find the return charage and replace with string terminator
    for (int i = 0; i < strlen(received); i++)
    {
        if (received[i] == '\n') {
            received[i] = '\0';
        }
    }

    return received;
}

char* reverse(char string[]) {
    static char reversed[100];
    int len = strlen(string);
    for (int i = 0; i < len; i++)
    {
        reversed[len - 1 - i] = string[i];
    }
    return reversed;
}

char* from_base_10(char num[], int base) {
    //NOTE: this function isnt finished and is not actually use yet....
    static char new_num[100];
    int numInt = atoi(num);
    int div;
    int rem;
    int count=0;

    if (base>36)
    {
        strcpy(new_num,"\nERROR: Base can not be higher than 36\n");
        return new_num;
    }

    while (numInt>0)
    {
        div = numInt / base;
        rem = numInt % base;
        //printf("%d \\ %d = %d remainder %d symbol = %c\n",numInt, base, div, rem, SYMBOLS[rem]);

        //can not use strcpy or strcat as a single char has no '\0' terminator
        new_num[count] = SYMBOLS[rem];

        count++;
        numInt = div;
    }
    new_num[count] = '\0';//finish the new string off

    //and now the new string has to be reversed
    strcpy(new_num, reverse(new_num));

    return new_num;
}

char* to_base_10(char num[], int base) {
    static char new_num[100];
    int len = strlen(num);
    int power;
    int total=0;
    char digit[2];//to use atoi() on a single char we still need a '\0' so didgit needs to be a 2 char string

    if (base > 36)
    {
        strcpy(new_num, "ERROR: Base can not be higher than 36.");
        return new_num;
    }

    for (int i = 0; i < len; i++)
    {
        power = len - 1 - i;
        digit[0] = num[i];
        //add digit times base to the power of its position in the number
        total += atoi(digit) * pow((double)base, (double)power);
    }
    printf("\n New Number is : %d\n", total);

    itoa(total, new_num, 10); //LOL and at this point I findout this function actually converts base at the same time.
    return new_num;
}


int main() {
    char* result;//accapts strings from input()
    result = "";//needs a value for strcmp to use it

    while (strcmp(result, "exit")!=0)
    {
        printf("\n\n\n Brads Math Functions \n");
        printf("======================\n");
        printf("Enter [exit] to quit.\n");
        printf("Enter [base] to convert numbers from one base to another.\n");
        result = input("\nEnter an option from the menu:");

        if (strcmp(result,"base")==0)
        {
            char num[100];
            strcpy(num, result=input("Enter a number:"));
            int end = atoi( input("Enter base:"));
            printf("\nResult: %s\n", to_base_10(num, end));
        }
    }

    printf("\n");
    return 0;
}

首先,现有的计算机都不允许您存储“无限”的值。 实际上,考虑到当前宇宙可能是有限的,在我们的现实中没有办法做到这一点。

但是,如果要存储“大”数字(“大”表示超出C中任何现有数字数据类型的数字),则可能需要考虑将它们存储为char数组。 同样,您将受到虚拟地址空间的限制,您的应用程序已经获得了虚拟地址空间(请参阅参考资料 )。

您可能想看看C中的动态内存分配 ,这可能会对您有所帮助。

接受“无限制”大小的字符串输入:

getline(char **lineptr, size_t *n, FILE *stream) ,不是标准的,但通常在* nix中。 它将根据需要重新分配内存。 样本源代码

或编写有关fgets/fgetc根据需要重新分配内存的辅助函数。 样例代码


使用接受“无限制”大小的字符串输入的函数时,请务必谨慎。 从根本上讲,这是未来的安全漏洞,因为代码可以控制外部数据或使用户不堪重负。

相反,建议将字符串输入限制为一个较大的值。

#define N 1000000
char *ptr = malloc(N);
assert(ptr);
fgets(p, N, stdin);
...
free(ptr); 

注意:C内存分配功能的许多实现仅分配内存,直到需要时才“使用”内存。 因此,如果不完全需要大量分配,则不会耗尽内存。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM