C字符数组用户输入检查长度

3
我是一名有用的助手,可以为您翻译文本。

我用 scanf 读取了一个 char 数组,并想检查其长度是否大于15。

有时它能正常工作,但有时会出现错误 -> 核心已转储。

我的代码:

#include <stdio.h>

int checkArray(char string[], int length) {
    int i;
    for(i=0; string[i] != '\0'; i++);
    if(i > length) {
        return -1;
    }
    return 0;
}

int main ()
{
    const int length = 15;
    char x[15];
    scanf("%s", x);
    if(checkArray(x, length) == -1) {
        printf("max. 15 chars!");
        return 1;
    }
    return 0;
}
4个回答

5
x的最大长度只能是14个字符(其中14个用于字符,1个用于NUL-终止符),因为你把它存在了一个大小为15的缓冲区中。因此,尝试检查其长度是否小于15个字符是毫无意义的。
如果你试图在其中存储一个大于14的字符串,它将越过数组,并希望引发像你正在经历的错误一样的错误。可以选择使你的数组更大,以便它能够容纳超过15个字符,并使用%s的宽度说明符。
char x[30];

scanf("%29s", x); // read a maximum of 29 chars (replace 29 if needed
                  // with one less than the size of your array)

checkArray(x, 15);

你可以将 x 设为 17:15,其中一个用于字符串,一个用于溢出,另一个用于 \0 - Kevin

1

scanf 读入的字符串长度超过14个字符(留一个空间给 null 终止符)时,会破坏内存。然后,你的 checkArray() 方法有一些问题:

int checkArray(char string[], int length) {
    int i;

    // This next line could as well be a call to `strlen`.
    // But you shouldn't let it access `string` when `i` is >= `length`. 
    for(i=0; string[i] != '\0'; i++);

    // This should be `>=`.  If `i` is 15, you accessed (in the loop above)
    // `string[15]`, which is past the end of the array.
    if(i > length) {
        return -1;
    }

    return 0;
}

0

不要返回-1和0,而是返回其他东西,比如长度代替-1,i代替0,并相应地更改主函数中的条件。然后程序每次都会给出输出。(不知道逻辑,但这对我有效)


0

这是一个经典的缓冲区溢出。您需要限制所读取数据的长度:

scanf("%14s", x);

或者,你可以告诉scanf为你分配缓冲区:

char* x;
scanf("%as", &x);
...
checkArray(x, 15);

这将分配一个足够长的缓冲区来容纳任何字符串 (当然,物理内存和恶意用户发送10GB数据给您的应用会有限制)。

这个字符串是动态分配的,所以在使用结束后需要释放它:

free(x);

他想知道用户是否输入了超过15个字符。 - Alin
在你编辑并添加动态分配部分之前,它就是这样的。 - Alin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接