c - 返回由从输入读取的行组成的字符串

标签 c string pointers input

我正在尝试编写一个 C 函数,该函数返回从输入中读取的一行作为 char*。我在 Windows 上,我通过将文件作为我的程序的输入和输出来在命令行中测试我的程序,如下所示:

cl program.c
program < test_in.txt > test_out.txt

这是我的(不工作的)功能:

char* getLine(void)
{
    char* result = "";
    int i, c;

    i = 1;
    while((c = getchar()) != EOF)
    {
         *result++ = c;
         i++;

         if(c == '\n')
            return result - i;
    }

    return result - i;
}

我期待它能工作,因为我之前写道:

char* getString(char* string)
{

    //char* result = string; // the following code achieve this.
    char* result = "";
    int i;

    for(i = 1; *result++ = *string++; i++);

    return result - i;
}

并且这些代码行具有正确的行为。

即使每个答案都会受到赞赏,我也会非常感激 如果你们有人能解释为什么我的 getString() 函数可以工作而我的 getLine() 函数不能工作

最佳答案

您的函数没有为正在读取的字符串分配足够的空间。变量 char* result = ""定义了一个指向字符串文字("",空字符串)的 char 指针,并且您将一些任意数量的字符存储到 result 指向的位置。

char* getLine(void)
{
    char* result = ""; //you need space to store input
    int i, c;

    i = 1;
    while((c = getchar()) != EOF)
    {
        *result++ = c; //you should check space
        i++;

        if(c == '\n')
            return result - i; //you should null-terminate
    }
    return result - i; //you should null-terminate
}

您需要为您的字符串分配空间,这具有挑战性,因为您事先不知道需要多少空间。因此,您需要决定是限制阅读量(ala fgets),还是在阅读更多时动态重新分配空间。另外,如何表示输入完成(到达EOF)?

以下替代方案假定动态重新分配是您选择的策略。

char* getLine(void)
{
    int ch; int size=100; size_t pos=0;
    char* result = malloc(size*sizeof(char*));
    while( (ch=getchar()) != EOF )
    {
        *result++ = ch;
        if( ++pos >= size ) {
            realloc(result,size+=100);
            //or,realloc(result,size*=2);
            if(!result) exit(1); //realloc failed
        }
        if( c=='\n' ) break;
    }
    *result = '\0'; //null-terminate
    return result - pos;
}

当您处理完上述函数返回的字符串后,请记住 free() 分配的空间。

此替代方案假设您提供了一个缓冲区来存储字符串(并指定了缓冲区的大小)。

char* getLine(char* buffer, size_t size)
{
    int ch;
    char* result = buffer;
    size_t pos=0;
    while( (ch=getchar()) != EOF )
    {
        *result++ = ch;
        if( ++pos >= size ) break; //full
        if( c=='\n' ) break;
    }
    *result = '\0'; //null-terminate
    return buffer;
}

两者都避免了检测 EOF 和有足够的空间来存储读取的字符之间的微妙交互。解决方案是在读取时缓冲一个字符,但没有足够的空间,然后在后续读取时将其注入(inject)。您还需要 null-ter

关于c - 返回由从输入读取的行组成的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33928227/

相关文章:

c++ - 在 C 中修改一个 char* 字符串

java - 将字符串类型引用标记为 volatile 安全吗?

python - 当读取具有某些字符的某些数据时, string.count() 会大幅减慢

C++ 指针和动态数组以及删除运算符

c - 从指针数组中删除指向任何泛型类型的重复指针

c - 如何连接指针数组?

c - 在 C 中转发可变参数函数的调用

c - 如何在 C 中反转字符串(不在适当的位置)?

C 编程中使用正则表达式检查字符串是否全是字母数字

c# - 将重复小数格式化为分数