c - 不知道如何实现指向 char 指针数组的指针

标签 c arrays pointers

我不太擅长使用指针。我知道足以让指向 char 的指针数组起作用,如下面的第一个示例所示。但我不想传递整个指针数组,因为它占用了堆栈上太多的空间。我想做的是将单个指针传递给为指针数组分配的内存。我不知道该怎么做。

该程序有效:

#include "pch.h"
#include "$StdHdr.h"
#include "TmpTstPtr1.h"

#define SRC_LIN_SIZ 150

int main(int ArgCnt, char * ArgVal[])
{
    char        InpFilPth[MAX_PATH + 1];
    FILE        * InpFilPtr;
    char        ** SrcArr;
    unsigned    Sub1;
    unsigned    SrcArrCnt = 0;

    strncpy_s(InpFilPth, "TmpTstPtr1.cpp", strlen("TmpTstPtr1.cpp"));
    fopen_s(&InpFilPtr, InpFilPth, "r");
    SrcArr = (char **)malloc(999999 * sizeof(char *));
    LodSrcArr(InpFilPtr, SrcArr, &SrcArrCnt);
    for (Sub1 = 0; Sub1 < SrcArrCnt; Sub1++) {
        printf("SrcArr[%d] = %s\n", Sub1, SrcArr[Sub1]);
    }
    fclose(InpFilPtr);

    return 0;
}

void LodSrcArr(FILE * InpFilPtr, char ** SrcArr, unsigned * SrcArrCnt)
{
    char        SrcLin[SRC_LIN_SIZ + 1];
    char        * GetStrPtr;


    GetStrPtr = GetStr(SrcLin, SRC_LIN_SIZ, InpFilPtr);
    while (GetStrPtr != NULL) {
        SrcArr[*SrcArrCnt] = (char *)malloc(SRC_LIN_SIZ + 1);
        //      CpySiz(SrcArr[*SrcArrCnt], strlen(SrcLin) + 1, SrcLin);
        errno = strncpy_s(SrcArr[*SrcArrCnt], SRC_LIN_SIZ + 1, SrcLin, strlen(SrcLin));
        (*SrcArrCnt)++;
        GetStrPtr = GetStr(SrcLin, SRC_LIN_SIZ, InpFilPtr);
    }
}


char * GetStr(char * Str, const int MaxChr, FILE * InpFilPtr)
{
    char        * InpRtnVal = NULL;
    unsigned    Sub1;

    //  Get string from input file.  Find the end of the string if something entered.
    InpRtnVal = fgets(Str, MaxChr + 1, InpFilPtr);
    if (InpRtnVal != NULL) {
        Sub1 = 0;
        while (Str[Sub1] != '\n' && Str[Sub1] != '\0') {
            Sub1++;
        }
        //  Replace newline with null.
        if (Str[Sub1] == '\n') {
            Str[Sub1] = '\0';
        }
    }
    return InpRtnVal;

以下程序根本无法接近:

#include "pch.h"
#include "$StdHdr.h"
#include "TmpTstPtr2.h"

#define SRC_LIN_SIZ 150

int main(int ArgCnt, char * ArgVal[])
{
    char        InpFilPth[MAX_PATH + 1];
    FILE        * InpFilPtr;
    char        ** SrcArr;
    unsigned    Sub1;
    unsigned    SrcArrCnt = 0;
    char        *** SrcArrPtr = NULL;

    strncpy_s(InpFilPth, "TmpTstPtr2.cpp", strlen("TmpTstPtr2.cpp"));
    fopen_s(&InpFilPtr, InpFilPth, "r");
    SrcArr = (char **)malloc(999999 * sizeof(char *));
    SrcArrPtr = &SrcArr;
    LodSrcArr(InpFilPtr, SrcArrPtr, &SrcArrCnt);
    SrcArrPtr = &SrcArr;
    for (Sub1 = 0; Sub1 < SrcArrCnt; Sub1++) {
//      printf("SrcArr[%d] = %s\n", Sub1, SrcArr[Sub1]);    // got "Exception thrown: read access violation. it was 0xCDCDCDCD."
        printf("SrcArr[%d] = %s\n", Sub1, **SrcArrPtr);     // get 75 lines of garbage
        (**SrcArrPtr) += sizeof(char *);
    }
    fclose(InpFilPtr);

    return 0;
}


void LodSrcArr(FILE * InpFilPtr, char *** SrcArrPtr, unsigned * SrcArrCnt)
{
    char        SrcLin[SRC_LIN_SIZ + 1];
    char        * GetStrPtr;


    GetStrPtr = GetStr(SrcLin, SRC_LIN_SIZ, InpFilPtr);
    //  while (GetStrPtr != NULL and *SrcArrCnt == 0) {
    while (GetStrPtr != NULL) {
        **SrcArrPtr = (char *)malloc(SRC_LIN_SIZ + 1);
        //      CpySiz(SrcArr[*SrcArrCnt], strlen(SrcLin) + 1, SrcLin);
        errno = strncpy_s(**SrcArrPtr, SRC_LIN_SIZ + 1, SrcLin, strlen(SrcLin));
        (**SrcArrPtr) += sizeof(char *);
        (*SrcArrCnt)++;
        GetStrPtr = GetStr(SrcLin, SRC_LIN_SIZ, InpFilPtr);
    }
}


char * GetStr(char * Str, const int MaxChr, FILE * InpFilPtr)
{
    char        * InpRtnVal = NULL;
    unsigned    Sub1;

    //  Get string from input file.  Find the end of the string if something entered.
    InpRtnVal = fgets(Str, MaxChr + 1, InpFilPtr);
    if (InpRtnVal != NULL) {
        Sub1 = 0;
        while (Str[Sub1] != '\n' && Str[Sub1] != '\0') {
            Sub1++;
        }
        //  Replace newline with null.
        if (Str[Sub1] == '\n') {
            Str[Sub1] = '\0';
        }
    }
    return InpRtnVal;
}

正如评论所说,当我尝试通过下标访问 SrcArr 时,出现运行时错误。当我尝试通过指针访问时,我得到了垃圾。问题可能出在我说 SrcArrPtr = &SrcArr; 的地方。我不知道这是否重要,但是打印的垃圾信息在接下来的每一行中都短了 4 个字符。就好像它实际上打印的是指针数组本身,而不是它们指向的字符串。我不知道。

我按照上面的方式编码的原因是为了让程序能够编译。我以前从未尝试过使用 3 指针。我想做的事情可能吗?如果是这样,有人可以告诉我怎么做吗?对其工作原理的解释会很好,但不是必需的。 (我正在使用 Visual Studio 2017,尽管我认为这并不重要。)

TIA。

最佳答案

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

void foo(char* bar[10]) { // a real array
    for (int i = 0; i < 10; ++i) {
        bar[i] = calloc(2, 1);
        bar[i][0] = '0' + i;
    }
}

void xox(char **qux) { // pointer to some char-pointers on the heap
    for (int i = 0; i < 10; ++i) {
        qux[i] = calloc(2, 1);
        qux[i][0] = '0' + i;
    }
}

int main(void)
{
    char* bar[10]; // a "real" array
    foo(bar);

    for (size_t i = 0; i < 10; ++i)
        puts(bar[i]);
    putchar('\n');

    // cleanup:
    for (size_t i = 0; i < 10; ++i)
        free(bar[i]);

    // plan b:
    char **qux = calloc(10, sizeof(*qux));
    xox(qux);

    for (size_t i = 0; i < 10; ++i)
        puts(qux[i]);
    putchar('\n');

    // cleanup:
    for (size_t i = 0; i < 10; ++i)
        free(qux[i]);
    free(qux);
}

关于c - 不知道如何实现指向 char 指针数组的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52516493/

相关文章:

php - 从数组中的一个查询中插入多行

java - 将整数对象的 ArrayList 转换为 int 数组?

C++ n00b学习指针,试图返回一个指向数组的指针

c - C中Typedef结构体的使用

c - 使用 perl XS 链接到 C 共享库

python - numpy:如何在 np 数组中选择特定索引以进行 k 折交叉验证?

c++ - 简单检查 dynamic_cast c++

#ifdefs 中打印值的更改,C

c - C 中的菜单驱动程序对链表执行各种操作

java - 如何在用户计算机上启动本地端口(编辑问题)