【问题标题】:输出指针返回 (null) 而不是 char 值
【发布时间】:2022-01-22 03:06:20
【问题描述】:

如果 Exam 函数的 *pMonthToStudy 参数等于相应人员的出生月份(birthDates[] 顺序对应于 names[] 顺序),则下面的程序必须返回指向从 names[] 获取的名称数组的指针。在六月的情况下,函数应该返回“John, James, Richard”。输出的视图必须与我的示例完全相同。

我分配的内存是否正确? 如果是,如何将这些值分配给返回指针并在 main 中正确输出(如果我的输出方法不正确)?

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

typedef struct {
    int day;
    char month[4];
    int year;
} DATE;

DATE birthDates[] = {{2, "Jun", 2000}, {27, "Jul", 2001}, {12, "Jun", 1999},
                     {15, "Sep", 1998}, {16, "Jun", 2000}};

char names[] = {"John, Mary, James, Elizabeth, Richard"};

char *Exam(char *pNames, DATE *pBirthDates, const char *pMonthToStudy){
    //Check if input ptr are zero or point to empty strings
    if(!pNames || !*pNames || !pBirthDates)
        return 0;
    char *pOutput = (char*) malloc(sizeof(*pNames));
    for (int i = 0; i < 5; ++i) {
        if(strcmp(pMonthToStudy, &birthDates->month[i]) == 0){
            strcpy(pOutput, &pNames[i]);
        } else
            return 0;
    }
    return pOutput;
}
int main() {
    char *pResult = Exam(names, birthDates, "Jun");
    printf("%s", pResult);
    return 0;
}

【问题讨论】:

  • char *pOutput = (char*) malloc(sizeof(*pNames)); 分配 1 个字节。当您将数组传递给函数时,您还需要在单独的参数中传递它的长度。
  • 表达式*pNamespNames[0] 相同。而pNames[0] 是一个单一的char。所以sizeof(*pNames) 是单个char 的大小,它总是1。所以你只为你的字符串pOutput分配一个字节。它可以保存的唯一以 null 结尾的字符串是空字符串 ""
  • 不确定char names[] = {"John, Mary, James, Elizabeth, Richard"}; 是否符合您的预期。
  • &amp;birthDates-&gt;month[i] 应该是birthDates[i].month

标签: arrays c loops struct c-strings


【解决方案1】:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    int day;
    char month[4];
    int year;
} DATE;

DATE birthDates[] = { {2, "Jun", 2000}, {27, "Jul", 2001}, {12, "Jun", 1999},
                     {15, "Sep", 1998}, {16, "Jun", 2000} };

const char *names[] = { "John", "Mary", "James", "Elizabeth", "Richard" };

char *Exam(const char **pNames, DATE *pBirthDates, const char *pMonthToStudy) {
    if (!pNames || !*pNames || !pBirthDates)
        return 0;
    char *pOutput = NULL;
    const char * prefix = ", ";
    int nSize = 0;
    int nCount = 0;
    int *arrIndexes = new int[5];

    for (int i = 0; i < 5; i++) {
        if (strcmp(pMonthToStudy, birthDates[i].month) == 0) {
            nSize += strlen(pNames[i]);

            arrIndexes[nCount] = i;

            nCount++;
        }
    }

    const int mallocSize = (nSize + (nCount - 1) * sizeof(prefix)) * sizeof(char) + 1;
    pOutput = (char*)(malloc(mallocSize));

    memset(pOutput, 0, mallocSize);

    for (int i = 0; i < nCount; i++) {
        strcat_s(pOutput, mallocSize, pNames[arrIndexes[i]]);

        if (i != nCount - 1) {
            strcat_s(pOutput, mallocSize, prefix);
        }
    }

    return pOutput;
}
int main() {
    char *pResult = Exam(names, birthDates, "Jun");
    printf("%s", pResult);
    return 0;
}

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
【解决方案2】:

首先声明此声明

char names[] = {"John, Mary, James, Elizabeth, Richard"};

声明一个字符数组,其中一个元素包含字符串文字

"John, Mary, James, Elizabeth, Richard"

作为此声明的结果

char *pOutput = (char*) malloc(sizeof(*pNames));

只分配了一个字符。

您的意思似乎是一个包含 5 个指向字符串文字的指针元素的数组

char * names[] = { "John", "Mary", "James", "Elizabeth", "Richard"};

但在这个声明中,初始化错误

char *pOutput = (char*) malloc(sizeof(*pNames));

您需要分配一个字符数组,该数组可以在数组名称中存储相应的字符串字面量。

如果找到目标记录,则必须在 for 循环之后进行此分配。否则函数会发生内存泄漏。

for循环不正确

for (int i = 0; i < 5; ++i) {
    if(strcmp(pMonthToStudy, &birthDates->month[i]) == 0){
        strcpy(pOutput, &pNames[i]);
    } else
        return 0;
}

它可以在循环的第一次迭代中返回 0,或者即使找到目标记录也可以返回 0,因为在这种情况下您没有中断循环。此外,您在函数strcmpstrcpy 中使用了不正确的表达式。

改为写

char *pOutput = NULL;

int i = 0;

while ( i < 5 && strcmp( pMonthToStudy, birthDates[i].month ) != 0 ) ++i;


if ( i != 5 )
{
    pOutput = malloc( strlen( pNames[i] ) + 1 );
    if ( pOutput != NULL ) strcpy( pOutput, pNames[i] );
}

return pOutput;

请注意,在函数中使用幻数 5 是个坏主意。您应该通过函数参数传递引用数组中元素的数量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多