c# c -使用scanf从用户读取字符串时读取位置异常时的访问冲突

bf1o4zei  于 2023-01-07  发布在  C#
关注(0)|答案(1)|浏览(208)

我尝试从用户读取字符串输入,并使用指针将其存储在二维数组中。当尝试使用这些字符串时,我遇到了读取位置异常的访问冲突。首先,我声明了将存储二维数组指针的char***,然后我使用for循环为每个单元格初始化二维数组。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WORDLEN 80
#define DEFLEN 200
#define KEYVALUE 2

char*** MallocDic(int dictionarySize);
char** MallocDicElement(char* word, char* definition);
void PrintDictionary(char*** dictionary, int dictionarySize);
int main()
{
    int dictionarySize;
    printf("Please enter dictionary size\n");
    scanf("%d", &dictionarySize);
    char*** dictionary = MallocDic(dictionarySize);

    int i;
    for (i = 0; i < dictionarySize; i++) {
        char* inputWord = (char*)malloc(WORDLEN * sizeof(char));
        char* inputDef = (char*)malloc(DEFLEN * sizeof(char));
        if (inputWord == NULL || inputDef == NULL)
        {
            printf("Failed to allocate memory!\n");
            exit(1);
        }
        printf("enter word : \n");
        scanf("%s", inputWord);
        printf("enter definition : \n");
        scanf("%s", inputDef);

        printf("word : %s ,def : %s\n", inputWord, inputDef);
        //dictionary[i] = MallocDicElement(inputWord, inputDef);
        //free(inputDef);
        free(inputWord);
    }
    printf("Print Dictionary : \n");
    //PrintDictionary(dictionary, dictionarySize);
}
char*** MallocDic(int dictionarySize) {
    char*** p;
    p = (char***)malloc(dictionarySize * sizeof(char**));
    return p;
}
char** MallocDicElement(char* word, char* definition) {
     char** p = (char**)malloc(KEYVALUE * sizeof(char*));
    int i;
    for (i = 0; i < KEYVALUE; i++) {
        if (i == 0) {
            p[i] = (char*)malloc(WORDLEN * sizeof(char));
            p[i] = word;
        }
        else {
            p[i] = (char*)malloc(DEFLEN * sizeof(char));
            p[i] = definition;
        }
    }
    return p;
}
void PrintDictionary(char*** dictionary, int dictionarySize) {
    int i = 0, j = 0;
    for (i = 0; i < dictionarySize; i++) {
        for (j = 0; j < KEYVALUE; j++) {
            printf("word : %s\n", dictionary[i][0]);
            printf("definition : %s\n", dictionary[i][1]);
        }
    }
}

当试图打印第一个字符串时,逻辑中断了。我在这里遗漏了什么?
谢谢你的帮助。

vlf7wbxs

vlf7wbxs1#

至少这些问题。

    • 内存泄漏**

代码分配内存并将指向该分配的指针保存到p[i],然后将 * 指针 * word复制到下一行的p[i]。这将丢失从malloc()返回的指针。

p[i] = (char*)malloc(WORDLEN * sizeof(char));
p[i] = word; // ???

OP更有可能希望将word指向的字符串复制到p[i]指向的内存中。

p[i] = malloc(WORDLEN);
strcpy(p[i], word);

更常见的是只分配需要的部分。

p[i] = malloc(strlen(word) + 1);
strcpy(p[i], word);

研究strdup()
为简洁起见,省略了错误检查。

    • 请勿在*scanf()中使用没有 * 宽度 * 的"%s""%[]"**

将可接受的输入限制为比目标数组的大小小1。

    • "%s"不读取和节省空间**

下面的语句将无法读取包含空格的定义。

printf("enter definition : \n");
scanf("%s", inputDef);  // Stops after first word

读取一些非空白后,扫描将在第一个空白处停止。
或许:

scanf(" %199[^\n]", inputDef);
    • 检查输入函数的返回值**
if (scanf(" %199[^\n]", inputDef) != 1) {
  Handle_input_error();
}

其他:

    • 避免难以读取和维护分配**

不是强制类型转换(不需要)和大小转换为类型(在其他地方定义),而是分配为被引用对象的大小--类型不需要出错。

// p = (char***)malloc(dictionarySize * sizeof(char**));
p = malloc(sizeof p[0] * dictionarySize);

更易于正确编码、审查和维护。

相关问题