将字符串指针发送到函数

时间:2011-10-04 19:19:57

标签: c

我正在参加我的第一个C编程课程,我遇到了一个问题,试图编写一个一次读取一行文本文件的函数。这是我的代码:

#define LINELENGTH 81

int getLine(char* line, FILE* file) {

    if (line == NULL) {
        line = malloc(sizeof(char) * LINELENGTH);
    }

    fgets(line, LINELENGTH, file);
    int length = strcspn(line, "\n");
    if (line[length] == '\n') {
        line[length] = '\0';
        line = realloc(line, sizeof(char) * (length + 1));
        return length;
    } else {
        char* addThis = NULL;
        int addedLength = getLine(addThis, file);
        length += addedLength;
        line = realloc(line, sizeof(char) * length);
        strcat(line, addThis);
        free(addThis);
        addThis = NULL;
        return length;
    }
}

int main() {
    FILE *text = fopen("test.txt", "r");
    char* line = NULL;
    getLine(line, text);
    printf("The first line is \"%s\"", line);
    fclose(text);
    free(line);
    return 0;
}

我的测试输入文件现在只包含一行“test”

当我运行程序时,我得到“第一行是”(null)“”。不是我所希望的。当我通过调试器中的函数步进时,一切似乎在getLine中正常工作。但是当函数返回时,我剩下的都是null。

感谢任何帮助。感谢。

5 个答案:

答案 0 :(得分:2)

getLine的调用是按值传递char*指针。在该函数中对line的赋值不会导致分配的指针返回给调用者。函数声明应该是:

int getLine(char** line, FILE* file) {...

然后将结果分配给*line。对函数的调用需要传递地址:

getLine( &line, text );

您还可以在函数内部使用局部变量,然后在返回之前将最终结果分配给*line。这可能会使代码更容易理解。否则,每次使用line时,都需要取消引用指针,并且它(我的意见在这里)有点麻烦。因此,可以将函数定义中的参数更改为getLine( char** retLine, ... )。然后声明char* line;形式的局部变量。然后在return语句之前,分配它:

*retLine = line;

一个非常不完整的例子:

int getLine( char **retLine, FILE *file ) {    
  *retLine = NULL;  // make sure we don't return garbage if error occurs
  char *line = malloc( ... );
  // do stuff with line, fill it up, etc.
  ...
  // assign the final result to the output param
  *retLine = line;
  return length;
}

这基本上是一个偏好问题。否则,必须进行解除引用。例如,

*line = malloc(...);
int length = strcspn( *line, ... );

答案 1 :(得分:1)

“line”是一个指针,你的getLine函数只改变'line'的复制值,它不会改变它自己的“line”指针。对于您的情况,您应该尝试

int main() {
    // ..
    line = malloc(sizeof(char) * LINELENGTH);
    getLine(line, text);
    // ..
}

答案 2 :(得分:0)

您需要更改getLine函数以及调用它的方式,以便它可以修改传递它的指针。现在,您只需在分配或重新分配行时修改函数内的本地副本。

而不是

int getLine(char* line, FILE* file) {

你需要

int getLine(char **line, FILE *file) {

然后,在getLine内,您需要取消引用line,只要您使用它来指向它所指向的指针,例如:

*line = malloc(sizeof(char) * LINELENGTH);

...和...

(*line)[length] = '\0';

......以及line的其他用途。

如果你可以摆脱递归和strcat,你也可以提高你的功能效率,虽然上面的改变应该让它起作用。

答案 3 :(得分:0)

好像你走了很长一段路,我会做这样的事情:

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

char line[1000];

int main()
{
FILE *file;
file = fopen("test.txt", "r");

fgets(line, sizeof(line), file);
printf("First line: %s", line);
memset(line, 0, strlen(line));
fclose(file);
return 0;
}

如果需要,您可以将其合并到一个函数中。 或者,如果你想让它列出整个文件,你可以简单地这样做:

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

char line[1000];

int main()
{
FILE *file;
file = fopen("test.txt", "r");

while(!feof(file))
{
fgets(line, sizeof(line), file);
printf(line);
memset(line, 0, strlen(line));
}

fclose(file);
return 0;
}

答案 4 :(得分:0)

考虑到你没有指针指针。

我建议更改方法签名如下:

char* getLine(int *len, FILE* file);
// instead of assigning the value to line like in your case, return it.

用法是:

int main() {
  .
  .
  .
  int length;
  char* line = NULL;
  line = getLine(&len, text);
  .
  .
}

另外,我发现你没有使用返回值,即main()中行的长度。所以你可以完全省略长度字段,并有一个像这样的方法定义:

char* getLine(FILE* file);