简体   繁体   English

在C中发布访问字符指针数组的内容

[英]Issue accessing contents of array of character pointers in C

I am going through The C Programming Language by K&R and trying to understand character pointers and arrays. 我正在研究K&R的C编程语言,并试图理解字符指针和数组。

I am creating a function in C that reads multiple lines from stdin and stores the lines ( char* ) in an array of character pointers ( char* [] ). 我正在C中创建一个函数,该函数从stdin读取多行并将行( char* )存储在字符指针数组( char* [] )中。

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

enum {MAXINPUT = 1024, MAXLINES = 100};

/* Reads at most `maxLines` lines and stores them in an array of char pointers. Returns number of lines read. */
int readlines(char* lineptr[], int maxLines);

/* Takes a single line input from stdin and stores it in str. Returns str length. */
int getInputLine(char* str, int maxInput);

int main(int argc, char** argv) { ... }

int readlines(char* lineptr[], int maxLines) {
    /* Return number of lines read. */
    int numLines = 0;
    /* Buffer to store current line being read. */
    char currentLine[MAXINPUT];

    /* Terminate loop when enter is pressed at empty input or number of lines exceeds max. */
    while(getInputLine(currentLine,MAXINPUT) && numLines < maxLines) {
        /* Address of current line's first character is set to the appropriate index at lineptr. */
        lineptr[numLines] = currentLine;

        /* Both currentLine and lineptr[numLines] print accurately (note they are the same). */
        printf("CURRENT LINE:\t %s\n",currentLine);
        printf("lineptr[%d]:\t %s\n",numLines,lineptr[numLines]);

        numLines++;
    }

    /* ISSUE: Outside the loop, lineptr does NOT print anything. */
    printf("\nLOOPING\n");
    for(int i = 0; i < numLines; i++) {
        printf("%d: %s\n",i,lineptr[i]);
    }

    /* ISSUE: currentLine (which should be the last line entered) ALSO does not print outside the while. */
    printf("\ncurrentLine: %s",currentLine);

    return numLines;
}

My issue is that in the while() , the contents of lineptr and currentLine print accurately. 我的问题是在while()lineptrcurrentLine的内容可以lineptr打印。 But outside the while() , both lineptr and currentLine do not print anything. 但是在while()lineptrcurrentLine都不打印任何内容。

And of course, this issue persists when I try to read lines into a char* [] in the main() and try to print its contents. 当然,当我尝试将行读入main()中的char* []并尝试打印其内容时,此问题仍然存在。

Why is it that the contents at the addresses being accessed by lineptr are printing inside the loop but not outside? 为什么lineptr访问的地址上的内容在循环内部而不是外部打印? Am I missing something obvious? 我是否缺少明显的东西?

That's because you have a single buffer called currentLine into which you read text. 那是因为您有一个称为currentLine缓冲区,您可以在其中读取文本。 Then you assign the address of currentLine to your lineptr[i] , and proceed to overwrite its contents with new text. 然后,将currentLine的地址分配给lineptr[i] ,并继续用新文本覆盖其内容。 So, all your lineptr s essentially point to the same one location, which is the address of currentLine , and currentLine contains only the last line that you read. 因此,您所有的lineptr本质上都指向同一位置,即currentLine的地址,而currentLine仅包含您读取的最后一行。 I suppose the loop does not print anything because the last line you read is empty. 我想循环不会打印任何内容,因为您读的最后一行是空的。

So, to get this to work, you need to read a line into currentLine , measure its length, use malloc() to allocate enough memory for that line, copy the line from currentLine to the allocated memory, and store the pointer to the allocated memory in lineptr[i] . 因此,要使其正常工作,您需要将一行读入currentLine ,测量其长度,使用malloc()为该行分配足够的内存,将该行从currentLine复制到分配的内存,并将指针存储到分配的内存中lineptr[i]内存。

This line 这条线

    lineptr[numLines] = currentLine;

just assigns a pointer to lineptr[numLines] . 只是将一个指针分配给lineptr[numLines] There are couple of issues with that: 有几个问题:

  1. Every line points to the same pointer. 每行指向相同的指针。
  2. The pointer is invalid after you return from the function. 从函数返回后,指针无效。

You need to use something akin to: 您需要使用类似于以下内容的东西:

    lineptr[numLines] = strdup(currentLine);

Remember that strdup is not a standard C library function. 请记住, strdup不是标准的C库函数。 If your platform does not support it, you can implement it very easily. 如果您的平台不支持它,则可以非常轻松地实现它。

char* strdup(char const* in)
{
    char* ret = malloc(strlen(in)+1);
    return strcpy(ret, in);
}

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

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