Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中创建get string函数时遇到的问题_C_String_Stdin_Cs50 - Fatal编程技术网

在C中创建get string函数时遇到的问题

在C中创建get string函数时遇到的问题,c,string,stdin,cs50,C,String,Stdin,Cs50,我正在尝试创建一个简单的函数,以安全的方式返回字符串,我想知道这段代码有什么问题。 我决定使用read,因为scanf和fgets都给e带来了麻烦, 具体地说,如果我在进行长度检查时缓冲区溢出,scanf会给出中止陷阱6, 当fgets接受输入时,如果插入的字符串太长,则返回错误消息,但无论如何都要预翻转该字符串,而不允许我重新输入另一个字符串。 代码如下: string get_string(const string prompt) { char temp[30]; int s

我正在尝试创建一个简单的函数,以安全的方式返回字符串,我想知道这段代码有什么问题。
我决定使用read,因为scanf和fgets都给e带来了麻烦, 具体地说,如果我在进行长度检查时缓冲区溢出,scanf会给出中止陷阱6,
当fgets接受输入时,如果插入的字符串太长,则返回错误消息,但无论如何都要预翻转该字符串,而不允许我重新输入另一个字符串。
代码如下:

string get_string(const string prompt)
{
    char temp[30];
    int size,count;
    printf("%s",prompt);
    do
    {
        count=read(0,temp,29);
        temp[count]='\0';
        size=strlen(temp);
        if(size>24)
        {
            printf("\x1B[31mError\x1B[0m: too long.\n%s",prompt);
        }
        printf("size :%i\n",size);
    }
    while(size>24);
    stripc(temp,'\n'); //removes new line
    string word=malloc((size)*sizeof(char));
    strcpy(word,temp);
    return word;
}
现在使用read时,它会给我类似的错误,我从stdin读取了总共30个字节,
然后我在计数器的末尾添加null字符,但如果长度超过,则输出为:

ppppppppppppppppppppppppppppp
Error: too long.
size :30
size :2
p
知道问题出在哪里吗?
有没有其他方法来实现我的需求

编辑:问题没有超出范围,
奇怪的是,一旦我写了超过24个字符,
应该读取输入(读取、扫描、fgets或其他)的函数,
不再激活,这就是为什么size:连续出现两次,
由于某种原因,输入插入被跳过,我想了解原因。

我更正了一些错误。

如果在第一次输入中没有找到换行符,请调用fgets,直到找到换行符,以便清理输入流,然后继续外部while循环

string get_string(const string prompt)
{
    char temp[26] = "";//24 + newline + '\0'
    int size,count;
    while ( 1)
    {
        printf ( "%s",prompt);
        if ( fgets ( temp, sizeof temp, stdin)) {
            if ( !strchr ( temp, '\n')) {//no newline
                printf("\x1B[31mError\x1B[0m: too long.\n%s",prompt);
                size = strlen ( temp);
                do {
                    fgets ( temp, sizeof temp, stdin);//read more and discard
                    size += strlen ( temp);
                } while (!strchr ( temp, '\n'));//loop until newline found
                printf("size :%i\n",size);
                continue;//re prompt
            }
            break;
        }
        else {
            fprintf ( stderr, "fgets problem\n");
            return NULL;
        }
    }

    temp[strcspn ( temp,"\n")] = '\0';//remove newline
    string word = malloc(strlen ( temp) + 1);
    strcpy ( word, temp);
    return word;
}

这是同一个老错误一遍又一遍

C中的字符串以null结尾。这意味着保存字符串的内存必须大于字符串的长度


您检查读取的字符串长度是否不超过24个字符,但是在malloc中,您没有为空字符添加空间。因此,
strcpy
将空字符放在指定内存之外。

如果您正在进行CS50练习,请将其添加为标记。否则人们会开始询问
字符串的类型是什么(它不是标准类型,由CS50头文件定义)。我在我的库中定义了字符串,当我使用stripc时,换行符将被删除,缺少一个字符,因此大小正好是容纳空字符的尺寸,我不需要输入大小+1。
temp[30]->
温度[30+1]
。同样,必须为空终止符预留malloc空间。还有一个bug导致了另一个bug,投票决定关闭这个bug。一旦答案开始出现,不要改变代码的性质——它会成为一个移动的目标。如果真的需要,可以追加。Post回滚。@chux是的,我会解决这个问题。谢谢它能工作,但我想知道如果我按自己的方式执行,获取输入的函数不能激活的原因。。。您能解释一下吗?之所以会发生这种情况,是因为第一次在stdin中写入的\n,但由于限制而没有在我的字符串中结束,这会干扰下一次读取,对吗?应该
fgets(temp,sizeof temp,stdin)
使用
temp[]
返回
NULL
。对于这段代码,可能是一个无限循环。空终止与这个问题无关,我在代码中加入了+1,但它并没有改变一个事实,即应该读取短语的函数在循环的第二次迭代中没有激活。我知道什么是空终止